MockMvc 与 RestTemplate 在集成测试中的区别

MockMvcRestTemplate都用于与 Spring 和 JUnit 的集成测试。

问题是,他们和我们应该选择其中一个的时候有什么区别?

下面是两种选择的例子:

//MockMVC example
mockMvc.perform(get("/api/users"))
.andExpect(status().isOk())
(...)


//RestTemplate example
ResponseEntity<User> entity = restTemplate.exchange("/api/users",
HttpMethod.GET,
new HttpEntity<String>(...),
User.class);
assertEquals(HttpStatus.OK, entity.getStatusCode());
35319 次浏览

使用 MockMvc,您通常需要设置整个 Web 应用程序上下文并模拟 HTTP 请求和响应。所以,虽然一个假的 DispatcherServlet已经启动并运行,模拟你的 MVC 栈将如何工作,但是没有真正的网络连接。

使用 RestTemplate,您必须部署一个实际的服务器实例来侦听您发送的 HTTP 请求。

正如在 < a href = “ https://spring.io/blog/2012/11/12/spring-Framework-3-2-rc1-spring-mvc-test-Framework”rel = “ nofollow noReferrer”> 这篇文章中所说的 物品你应该使用 MockMvc当你想测试 服务器端的应用:

Spring MVC Test 构建于来自 spring-test的模拟请求和响应,不需要运行的 servlet 容器。主要区别在于,实际的 Spring MVC 配置是通过 TestContext 框架加载的,请求是通过实际调用 DispatcherServlet和运行时使用的所有相同的 Spring MVC 基础结构来执行的。

例如:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration("servlet-context.xml")
public class SampleTests {


@Autowired
private WebApplicationContext wac;


private MockMvc mockMvc;


@Before
public void setup() {
this.mockMvc = webAppContextSetup(this.wac).build();
}


@Test
public void getFoo() throws Exception {
this.mockMvc.perform(get("/foo").accept("application/json"))
.andExpect(status().isOk())
.andExpect(content().contentType("application/json"))
.andExpect(jsonPath("$.name").value("Lee"));
}}

当你想测试 客户端休息应用程序时,你应该使用 RestTemplate:

如果您有使用 RestTemplate的代码,那么您可能需要对其进行测试,您可以针对运行中的服务器或模拟 RestTemplate 进行测试。客户端 REST 测试支持提供了第三种选择,即使用实际的 RestTemplate,但是使用定制的 ClientHttpRequestFactory对其进行配置,该 ClientHttpRequestFactory根据实际请求检查期望值并返回存根响应。

例如:

RestTemplate restTemplate = new RestTemplate();
MockRestServiceServer mockServer = MockRestServiceServer.createServer(restTemplate);


mockServer.expect(requestTo("/greeting"))
.andRespond(withSuccess("Hello world", "text/plain"));


// use RestTemplate ...


mockServer.verify();

也读取 这个例子

可以同时使用 RestTemplate 和 MockMvc!

如果您有一个单独的客户机,在这个客户机上已经完成了从 Java 对象到 URL 的冗长映射以及与 Json 之间的转换,并且希望将其重用于 MockMVC 测试,那么这种方法非常有用。

下面是如何做到这一点:

@RunWith(SpringRunner.class)
@ActiveProfiles("integration")
@WebMvcTest(ControllerUnderTest.class)
public class MyTestShould {


@Autowired
private MockMvc mockMvc;


@Test
public void verify_some_condition() throws Exception {


MockMvcClientHttpRequestFactory requestFactory = new MockMvcClientHttpRequestFactory(mockMvc);
RestTemplate restTemplate = new RestTemplate(requestFactory);


ResponseEntity<SomeClass> result = restTemplate.getForEntity("/my/url", SomeClass.class);


[...]
}


}