Search code examples
javaspringspring-mvcjunitintegration-testing

Difference between MockMvc and RestTemplate in integration tests


Both MockMvc and RestTemplate are used for integration tests with Spring and JUnit.

Question is: what's the difference between them and when we should choose one over another?

Here are just examples of both options:

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

Solution

  • As said in this article you should use MockMvc when you want to test Server-side of application:

    Spring MVC Test builds on the mock request and response from spring-test and does not require a running servlet container. The main difference is that actual Spring MVC configuration is loaded through the TestContext framework and that the request is performed by actually invoking the DispatcherServlet and all the same Spring MVC infrastructure that is used at runtime.

    for example:

    @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"));
      }}
    

    And RestTemplate you should use when you want to test Rest Client-side application:

    If you have code using the RestTemplate, you’ll probably want to test it and to that you can target a running server or mock the RestTemplate. The client-side REST test support offers a third alternative, which is to use the actual RestTemplate but configure it with a custom ClientHttpRequestFactory that checks expectations against actual requests and returns stub responses.

    example:

    RestTemplate restTemplate = new RestTemplate();
    MockRestServiceServer mockServer = MockRestServiceServer.createServer(restTemplate);
    
    mockServer.expect(requestTo("/greeting"))
      .andRespond(withSuccess("Hello world", "text/plain"));
    
    // use RestTemplate ...
    
    mockServer.verify();
    

    also read this example