如何在Java的@SpringBootTest中使用MockMvc和MockRestServiceServer。

huangapple 未分类评论58阅读模式
英文:

How to use MockMvc and MockRestServiceServer in Java @SpringBootTest

问题

这是一段关于使用Spring Boot进行单元测试的代码。该代码的目标是编写一个@SpringBootTest单元测试,该测试既能够发出REST请求,又能够模拟REST响应。这样做的原因是,Spring应用程序会接收REST请求,并在响应中使用REST从另一个源获取信息。测试旨在通过发起REST GET请求(使用MockMvc)来触发应用程序,并且还希望模拟另一个源的响应(使用MockRestServiceServer)。

以下是代码的一部分,其中包含了测试和模拟的设置:

// 导入必要的类和库

@Slf4j
@ExtendWith(SpringExtension.class)
@SpringBootTest
@AutoConfigureMockMvc
class RestTest {
    private static final String URI = "/my-test-uri";
    private static final String RESPONSE = "my-response";
    @Autowired
    private MockMvc mockMvc;

    @Test
    void testRest() throws Exception {
        log.info("Initiating request for GET {}", URI);
        mockMvc.perform(get(URI))
                .andExpect(status().isOk())
                .andExpect(content().string(containsString(RESPONSE)));
    }
}

@TestConfiguration
static class TestConfig {

    @Primary
    @Bean
    public RestTemplateBuilder restTemplateBuilder() {
        RestTemplate restTemplate = new RestTemplate();
        MockRestServiceServer server = MockRestServiceServer.createServer(restTemplate);
        server.expect(requestTo(URI))
                .andRespond(withSuccess(RESPONSE, MediaType.APPLICATION_JSON));
        log.info("Mocking response to GET {}: {}", URI, RESPONSE);

        RestTemplateBuilder mockBuilder = mock(RestTemplateBuilder.class);
        when(mockBuilder.build()).thenReturn(restTemplate);
        return mockBuilder;
    }
}

根据您的描述,测试失败是因为它没有收到在TestConfig.restTemplateBuilder中定义的响应。您提供了REST请求者(testRest()方法)和REST响应者(TestConfig.restTemplateBuilder)。您在代码中使用了MockMvcMockRestServiceServer来模拟请求和响应。

以下是测试失败的错误信息:

Status expected:<200> but was:<404>
Expected :200
Actual   :404
<Click to see difference>

java.lang.AssertionError: Status expected:<200> but was:<404>
    at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:59)
    at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:122)
    at org.springframework.test.web.servlet.result.StatusResultMatchers.lambda$matcher$9(StatusResultMatchers.java:627)
    at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:196)
    at com.mycompany.RestTest.testRest(RestTest.java:54)
...
    at java.base/java.lang.Thread.run(Thread.java:830)

以上就是您提供的代码和错误信息的翻译。如果您有进一步的问题或需要解决方案,请随时提问。

英文:

I am attempting to write a @SpringBootTest which will both issue REST requests and mock responses. I want to do this because my spring application receives REST requests and in response it fetches information from another source using REST. I would like to trigger my application by initiating a REST GET (MockMvc), but would also like to mock the other source's response (MockRestServiceServer).

Here is a sanitized version of the test, with my application removed:

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.client.MockRestServiceServer;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.client.RestTemplate;

import static org.hamcrest.Matchers.containsString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@Slf4j
@ExtendWith(SpringExtension.class)
@SpringBootTest
@AutoConfigureMockMvc
class RestTest {
    private static final String URI = &quot;/my-test-uri&quot;;
    private static final String RESPONSE = &quot;my-response&quot;;
    @Autowired
    private MockMvc mockMvc;

    @Test
    void testRest() throws Exception {
        log.info(&quot;Initiating request for GET {}&quot;, URI);
        mockMvc.perform(get(URI))
                .andExpect(status().isOk())
                .andExpect(content().string(containsString(RESPONSE)));
    }

    @TestConfiguration
    static class TestConfig {

        @Primary
        @Bean
        public RestTemplateBuilder restTemplateBuilder() {
            RestTemplate restTemplate = new RestTemplate();
            MockRestServiceServer server = MockRestServiceServer.createServer(restTemplate);
            server.expect(requestTo(URI))
                    .andRespond(withSuccess(RESPONSE, MediaType.APPLICATION_JSON));
            log.info(&quot;Mocking response to GET {}: {}&quot;, URI, RESPONSE);

            RestTemplateBuilder mockBuilder = mock(RestTemplateBuilder.class);
            when(mockBuilder.build()).thenReturn(restTemplate);
            return mockBuilder;
        }
    }
}

The test fails because it does not receive the response defined in TestConfig.restTemplateBuilder. I am providing both the REST requestor (testRest() method) and the REST responder (TestConfig.restTemplateBuilder). What am I doing wrong?

Here's the failure:

Status expected:&lt;200&gt; but was:&lt;404&gt;
Expected :200
Actual   :404
&lt;Click to see difference&gt;

java.lang.AssertionError: Status expected:&lt;200&gt; but was:&lt;404&gt;
	at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:59)
	at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:122)
	at org.springframework.test.web.servlet.result.StatusResultMatchers.lambda$matcher$9(StatusResultMatchers.java:627)
	at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:196)
	at com.mycompany.RestTest.testRest(RestTest.java:54)
...
	at java.base/java.lang.Thread.run(Thread.java:830)

huangapple
  • 本文由 发表于 2020年5月5日 13:21:24
  • 转载请务必保留本文链接:https://java.coder-hub.com/61606261.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定