集成测试中MockMvc和RestTemplate之间的区别

时间:2014-09-17 23:34:52

标签: java spring spring-mvc junit integration-testing

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());

3 个答案:

答案 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);

        [...]
    }

}