MockMvc和RestTemplate都用于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());
答案 0 :(得分:33)
使用MockMvc
,您通常会设置整个Web应用程序上下文并模拟HTTP请求和响应。因此,虽然假的DispatcherServlet
启动并运行,模拟MVC堆栈的运行方式,但没有真正的网络连接。
使用RestTemplate
,您必须部署一个实际的服务器实例来侦听您发送的HTTP请求。
答案 1 :(得分:28)
如this所述
如果要测试应用程序的服务器端,则应使用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().mimeType("application/json"))
.andExpect(jsonPath("$.name").value("Lee"));
}}
当你想测试 Rest客户端应用程序时,你应该使用RestTemplate
:
如果你有使用
RestTemplate
的代码,你可能想要测试它,并且你可以针对正在运行的服务器或模拟RestTemplate。客户端REST测试支持提供了第三种替代方案,即使用实际的RestTemplate
,但使用自定义ClientHttpRequestFactory
对其进行配置,以检查对实际请求的预期并返回存根响应。
示例:
RestTemplate restTemplate = new RestTemplate();
MockRestServiceServer mockServer = MockRestServiceServer.createServer(restTemplate);
mockServer.expect(requestTo("/greeting"))
.andRespond(withSuccess("Hello world", "text/plain"));
// use RestTemplate ...
mockServer.verify();
还阅读了this example
答案 2 :(得分:15)
可以同时使用RestTemplate和MockMvc!
如果您有一个单独的客户端,您已经将Java对象的冗长映射到URL并转换为Json和从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);
[...]
}
}