In this tutorial, you will learn to implement a 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,@Serviceor@Repositorybeans) and instead apply only configuration relevant to MVC tests such as@Controllerand@ControllerAdviceAuto-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
@WebMvcTestclass annotation to test only Spring MVC components
Inject MockMVC with @Autowired
- Inject the
MockMVCfield into your test class, for example
@Autowired
private MockMvc mockMvc;
Mock dependencies with @MockBean
- Use
@MockBeanto 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'sperform(...)to perform a mock HTTP test request withMockMvcRequestBuilders - Use
JsonPathandHamcrestto 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