Integration and unit tests with MockMvc

3.7k views Asked by At

According to the documentation there are two ways to do this:

First:

@RunWith(SpringRunner.class)
@WebAppConfiguration
@ContextConfiguration("my-servlet-context.xml")
public class MyWebTests {

    @Autowired
    private WebApplicationContext wac;

    private MockMvc mockMvc;

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

    // ...

}

This form uses the actual context of the application.

And the second way:

public class MyWebTests {

    private MockMvc mockMvc;

    @Mock
    private MyService myService;

    @InjectMocks
    private MyController myController;

    @Before
    public void setup() {
        // Process mock annotations
        MockitoAnnotations.initMocks(this);
        this.mockMvc = MockMvcBuilders.standaloneSetup(myController)
                .setCustomArgumentResolvers(new PageableHandlerMethodArgumentResolver()).build();
    }

    @Test
    public void testsForPost() throws Exception {

        Foo foo = new Foo();

        //given
        given(myService.findById(Matchers.anyLong())).willReturn(foo);

        //when
        this.mockMvc.perform((post("/foo")))
        //then
        .andExpect(status().isMethodNotAllowed())
        .andDo(print());
    }   
    ...
}

With this method I am not using the application context.

My question is, can I consider the first form as integration tests? And the second as unit tests?

Otherwise what would be the best solution to do unit tests of SpringMVC.

1

There are 1 answers

0
Tom On

I, too, would consider the first an integration test and the second a unit test.

I think a well written MVC controller should be covered with an integration test and not a unit test. A controller should only orchestrate calls to mappers, services, repositories and the like. Since the mappers, services, repositories and the like should be covered with their own unit tests, you don't gain a lot by unit testing your controller.

An integration test is much more valuable in this case, since it tests the whole interaction between the controller and components it orchestrates. And using tools like DBUnit it is not much harder to write.