英文:
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
)。您在代码中使用了MockMvc
和MockRestServiceServer
来模拟请求和响应。
以下是测试失败的错误信息:
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 = "/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;
}
}
}
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:<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)
专注分享java语言的经验与见解,让所有开发者获益!
评论