In this tutorial, you will learn to implement unit test of the REST API and Controller layer in Spring Boot by using @WebMvcTest and MockMvc

@WebMvcTest is used in combination with @RunWith(SpringRunner.class) when a test focuses only on Spring MVC components. It provides the following features

  • Disable full auto-configuration (not @Component, @Service or @Repository beans) and instead apply only configuration relevant to MVC tests such as @Controller and @ControllerAdvice

  • Auto-configure Spring Security and MockMvc

Project dependencies

Include spring-boot-starter-test into your pom.xml file

<dependency>  
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
</dependency>  

spring-boot-starter-test contains some testing support libraries such as JUnit, Spring Test + Spring Boot Test, Mockito, AssertJ, Hamcrest and JsonPath

Define the test class

Run the tests with SpringRunner and @WebMvcTest

  • Use the @RunWith(SpringRunner.class) class annotation to tell JUnit to run the unit tests in Spring's testing supports
  • Use the @WebMvcTest class annotation to test only Spring MVC components

Inject MockMVC with @Autowired

  • Inject the MockMVC field into your test class, for example
@Autowired
private MockMvc mockMvc;  

Mock dependencies with @MockBean

  • Use @MockBean to mock API and Controller dependencies to the Spring ApplicationContext, for example
@MockBean
private ProductService productService;

@MockBean
private ProductMapper productMapper;  

Stub methods with Mockito's doReturn...when

  • Use Mockito.doReturn(...).when(aMock).doSomething(...) to give the test input, for example
// given
ProductDTO productDTO = ProductDTO.builder()  
    .name("P1")
    .description("P1 desc")
    .price(new BigDecimal("1"))
    .build();

List<ProductDTO> productDTOs = Arrays.asList(productDTO);

doReturn(new ArrayList<>()).when(productService).findAll();     

doReturn(productDTOs).when(productMapper).toProductDTOs(any());  

Perform the test with MockMVC's perform(...) and Verify the test result with JsonPath and Hamcrest

  • Use MockMVC's perform(...) to perform a mock HTTP test request with MockMvcRequestBuilders
  • Use JsonPath and Hamcrest to verify the JSON response data
// when + then
this.mockMvc.perform(get("/api/v1/products"))  
    .andExpect(status().isOk())
    .andExpect(jsonPath("$[0].name", is(productDTO.getName())));

Implementation example


Source code

https://github.com/hellokoding/hellokoding-courses/tree/master/springboot-examples/springboot-restapi-testing-all-layers