Spring Boot Mockito Controller Test Example

1. Overview

Testing controllers in Spring Boot applications ensures the correctness of HTTP request handling and response. This guide will demonstrate how to set up controller tests using Mockito.

Testing a Spring Boot controller involves simulating HTTP requests, invoking controller methods, and verifying the response. Mockito allows us to mock service layer dependencies, ensuring our tests remain isolated from external factors.

2. Development Steps

1. Set up a new Spring Boot project.

2. Define the model, service, and controller layers.

3. Write a unit test for the controller using Mockito and MockMvc from Spring Test.

4. Run the tests to validate the outcomes.

3. Dependencies (Mockito and JUnit 5)

<dependencies>
    <!-- Spring Boot Starter Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Spring Boot Test Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

4. Spring Boot Mockito Controller Test Example

// Model
public class Employee {
    private Long id;
    private String name;
    // getters, setters, constructors, etc.
}
// Service layer
@Service
public class EmployeeService {
    public Employee getEmployeeDetails(Long id) {
        // Suppose this method interacts with a database or another system.
        // For this example, we return a dummy employee.
        return new Employee(1L, "John Doe");
    }
}
// Controller layer
@RestController
@RequestMapping("/api/employees")
public class EmployeeController {
    @Autowired
    private EmployeeService service;
    @GetMapping("/{id}")
    public ResponseEntity<Employee> getEmployee(@PathVariable Long id) {
        Employee employee = service.getEmployeeDetails(id);
        if (employee != null) {
            return new ResponseEntity<>(employee, HttpStatus.OK);
        } else {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }
    }
}
// Test class
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;
@WebMvcTest(EmployeeController.class)
public class EmployeeControllerTest {
    @Autowired
    private MockMvc mockMvc;
    @MockBean
    private EmployeeService service;
    @Test
    public void testGetEmployee() throws Exception {
        Employee emp = new Employee(1L, "John Doe");
        Mockito.when(service.getEmployeeDetails(1L)).thenReturn(emp);
        mockMvc.perform(get("/api/employees/1"))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.name").value("John Doe"));
    }
}

Output:

The test testGetEmployee will pass, confirming that the EmployeeController correctly handles the GET request and returns the expected response.

Code Explanation:

- We use the @WebMvcTest annotation to specify that we are targeting the EmployeeController for testing.

- MockMvc allows us to perform HTTP requests in a test environment.

- The @MockBean annotation mocks the EmployeeService, ensuring that the controller test is not dependent on the actual service layer.

- In our test method, we define the behavior of the mocked service and then perform a GET request using mockMvc.

- The andExpect methods are used to verify the response.

5. Conclusion

Testing controllers in a Spring Boot application is crucial to ensure that incoming requests are handled correctly and the appropriate responses are returned. Using Mockito in conjunction with MockMvc offers a powerful combination for controller tests, ensuring that tests are isolated and focus solely on the controller's behavior.


Comments