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
,@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
'sperform(...)
to perform a mock HTTP test request withMockMvcRequestBuilders
- Use
JsonPath
andHamcrest
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