Learn to use Spring MockMVC to perform integration testing of Spring webmvc controllers. MockMVC class is part of Spring MVC test framework which helps in testing the controllers explicitly starting a Servlet container.
In this MockMVC tutorial, we will use it along with Spring boot’s WebMvcTest class to execute Junit testcases which tests REST controller methods written for Spring boot 2 hateoas example.
1. Maven Dependencies
The spring-boot-starter-test
dependency includes all required dependencies to create and execute tests.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency>
If not using spring boot then include following dependencies.
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>{version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>{version}</version> <scope>test</scope> </dependency>
2. Test Class Configuration
A JUnit test class to test the Spring MVC controller request and responses, we can use below given configuration.
@RunWith(SpringRunner.class) @WebMvcTest(EmployeeRESTController.class) public class TestEmployeeRESTController { @Autowired private MockMvc mvc; }
SpringRunner
is an alias for theSpringJUnit4ClassRunner
. It is a custom extension of JUnit’s BlockJUnit4ClassRunner which provides functionality of the Spring TestContext Framework to standard JUnit tests by means of the TestContextManager and associated support classes and annotations.@WebMvcTest
annotation is used for Spring MVC tests. It disables full auto-configuration and instead apply only configuration relevant to MVC tests.- The
WebMvcTest
annotation auto-configureMockMvc
instance as well. - Using
EmployeeRESTController.class
as parameter, we are asking to initialize only one web controller and you need to provide remaining dependencies required usingMock
objects.
3. Spring boot MockMvc tests example
Let’s create some JUnit tests which will test different HTTP methods in controller class.
3.1. HTTP GET
The HTTP APIs are defined in controller are given below. In given tests, we are testing two GET apis – one without path parameter and another with path parameter.
@GetMapping(value = "/employees") public EmployeeListVO getAllEmployees() { //code } @GetMapping(value = "/employees/{id}") public ResponseEntity<EmployeeVO> getEmployeeById (@PathVariable("id") int id) { //code }
And corresponding tests for the methods are given below. These tests hit the APIs, pass the path parameters using MockMvcRequestBuilders and verify the status response codes and response content using MockMvcResultMatchers and MockMvcResultHandlers.
@Autowired private MockMvc mvc; @Test public void getAllEmployeesAPI() throws Exception { mvc.perform( MockMvcRequestBuilders .get("/employees") .accept(MediaType.APPLICATION_JSON)) .andDo(print()) .andExpect(status().isOk()) .andExpect(MockMvcResultMatchers.jsonPath("$.employees").exists()) .andExpect(MockMvcResultMatchers.jsonPath("$.employees[*].employeeId").isNotEmpty()); } @Test public void getEmployeeByIdAPI() throws Exception { mvc.perform( MockMvcRequestBuilders .get("/employees/{id}", 1) .accept(MediaType.APPLICATION_JSON)) .andDo(print()) .andExpect(status().isOk()) .andExpect(MockMvcResultMatchers.jsonPath("$.employeeId").value(1)); }
3.2. HTTP POST
The HTTP POST API is defined in controller is:
@PostMapping(value = "/employees") public ResponseEntity<EmployeeVO> addEmployee (@Valid @RequestBody EmployeeVO employee) { //code return new ResponseEntity<EmployeeVO>(employee, HttpStatus.CREATED); }
And corresponding spring mockmvc test for post json request is as follows:
@Autowired private MockMvc mvc; @Test public void createEmployeeAPI() throws Exception { mvc.perform( MockMvcRequestBuilders .post("/employees") .content(asJsonString(new EmployeeVO(null, "firstName4", "lastName4", "email4@mail.com"))) .contentType(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isCreated()) .andExpect(MockMvcResultMatchers.jsonPath("$.employeeId").exists()); } public static String asJsonString(final Object obj) { try { return new ObjectMapper().writeValueAsString(obj); } catch (Exception e) { throw new RuntimeException(e); } }
3.3. HTTP PUT
The HTTP API is defined in controller is:
@PutMapping(value = "/employees/{id}") public ResponseEntity<EmployeeVO> updateEmployee (@PathVariable("id") int id, @Valid @RequestBody EmployeeVO employee) { //code return new ResponseEntity<EmployeeVO>(emp, HttpStatus.OK); }
And corresponding tests for the methods are:
@Test public void updateEmployeeAPI() throws Exception { mvc.perform( MockMvcRequestBuilders .put("/employees/{id}", 2) .content(asJsonString(new EmployeeVO(2, "firstName2", "lastName2", "email2@mail.com"))) .contentType(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(MockMvcResultMatchers.jsonPath("$.firstName").value("firstName2")) .andExpect(MockMvcResultMatchers.jsonPath("$.lastName").value("lastName2")) .andExpect(MockMvcResultMatchers.jsonPath("$.email").value("email2@mail.com")); }
3.4. HTTP DELETE
The HTTP API is defined in controller is:
@DeleteMapping(value = "/employees/{id}") public ResponseEntity<HttpStatus> removeEmployee (@PathVariable("id") int id) { //code return new ResponseEntity<HttpStatus>(HttpStatus.ACCEPTED); }
And corresponding tests for the methods are:
@Test public void deleteEmployeeAPI() throws Exception { mvc.perform( MockMvcRequestBuilders.delete("/employees/{id}", 1) ) .andExpect(status().isAccepted()); }
3.5. Test Results
When we run above tests, we get the test results as below.

4. Summary
In this spring boot integration test example, we learned to write Spring MVC integration tests using MockMvc class. He learned to write JUNit tests for HTTP GET, POST, PUT and DELETE APIs.
We also looked to verify API response status and response body, pass HTTP headers, and request path parameters as well.
Happy Learning !!
Read More:
asJsonString is giving errror it will give MIME does not contain ‘/’
For one of my POST API I am geting such response, whats the possible cause??
MockHttpServletResponse:
Status = 200
Error message = null
Headers = []
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.ClassCastException: org.springframework.web.servlet.resource.ResourceHttpRequestHandler cannot be cast to org.springframework.web.method.HandlerMethod
I am getting this error, any idea what is wrong?
Do you have any solution? I am getting the same exception
Hey , can we mock methods using MockMVC , if no How can we mock a method with the similar approach ?? Pleas do a session on that as well . A typical example of a method call “addValues(int a, int b)” whichj the adds , subtracts , multiplies, and divides a with b , and combines the entire result as one string and returns it.
Do you need to running service first to do Spring boot MockMvc tests ?
I got assertion error on line “status().isOk()”
It is static method from MockMvcResultMatchers.
Add the following to your REST API tests:
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
asJsonString is giving errror
What error you are facing. I hope you have defined the method as given in post :