Introduction to @WebMvcTest

Get introduced to testing utilities in Spring Boot.

Testing in Spring Boot

Spring Boot offers various utilities to start an application for testing, either fully or partially. We can use @SpringBootTest as a class annotation for a JUnit test which will start our complete application, including an embedded Tomcat to serve the HTML pages.

However, for tests that will only test a controller for example, we don’t need to start the full application.

Spring Boot has test slices that allows us to start, say, only the database layer (@DataJpaTest), the web layer (@WebMvcTest), or the JSON converters (@JsonTest), etc.

Using @WebMvcTest

We will use @WebMvcTest since it is the test slice we want for testing our UserController. The @WebMvcTest annotation will automatically configure a mock servlet environment. Using MockMvc, we can interact with our controller and validate requests and responses.

The following things will be created when using @WebMvcTest:

  • All @Controller beans (or only a single one when specifying the class name on the @WebMvcTest annotation).

  • All @ControllerAdvice beans.

  • All @JsonComponent beans, so custom JSON serializers and deserializers will be active.

  • org.springframework.core.convert.converter.Converter beans.

  • Filter beans.

  • WebMvcConfigurer beans.

  • HandlerMethodArgumentResolver beans.

  • Spring Security configuration beans.

What is not created?

  • @Component

  • @Service

  • @Repository

  • @Configuration

If our controller needs any of the above four, we should:

  • add them by using @Import.

  • add mock implementations by using @MockBean.

  • use @TestConfiguration with @Bean.

Why are we not doing plain unit tests for controllers?

You might wonder why we are immediately doing an integration test and not a plain unit test. In the case of a controller, there is quite a lot going on in terms of annotations interpreted by the Spring Framework and the security configuration of the application. Moreover, as a good rule of thumb, a controller should not contain much logic but should instead delegate to helper classes (Services and/or repositories). Given all that, the value of a plain unit test would be minimal.

Get hands-on with 1000+ tech skills courses.