Mockito @Mock Annotation Example

1. Overview

In many software applications, business logic and data access logic are separated into service and repository layers, respectively. When testing the service layer, it's often beneficial to mock the repository to ensure that it is tested in isolation. 

This tutorial will demonstrate how to mock the EmployeeService and EmployeeRepository using Mockito's @Mock annotation.

Introduction to @Mock 

The @Mock annotation is a shorthand way of creating mock objects. Instead of manually creating a mock using Mockito.mock(Class), you can annotate a field with @Mock to automatically create a mock instance.

2. Development Steps

1. Set up the Maven project.

2. Add the necessary dependencies.

3. Create the Employee Management System classes.

4. Implement unit tests using Mockito's @Mock annotation.

5. Execute and verify the tests.

3. Dependencies (Mockito and JUnit 5)

Create a simple Maven project and add the following Mockito and JUnit 5 dependencies:
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.10.0</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <version>5.6.0</version>
    <scope>test</scope>
</dependency>

4. Code Program

// Employee.java
public class Employee {
    private String name;
    private int id;
    // Constructors, getters, setters, etc.
}
// EmployeeRepository.java
public class EmployeeRepository {
    public boolean save(Employee employee) {
        // Logic to save employee to database
        return true;
    }
}
// EmployeeService.java
public class EmployeeService {
    private EmployeeRepository employeeRepository;
    public EmployeeService(EmployeeRepository employeeRepository) {
        this.employeeRepository = employeeRepository;
    }
    public boolean saveEmployee(Employee employee) {
        // Business logic before saving
        return employeeRepository.save(employee);
    }
}
// EmployeeServiceTest.java
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.when;
public class EmployeeServiceTest {
    @Mock
    private EmployeeRepository employeeRepository;
    @InjectMocks
    private EmployeeService employeeService;
    @Test
    public void testSaveEmployee() {
        MockitoAnnotations.openMocks(this);
        Employee employee = new Employee();
        when(employeeRepository.save(employee)).thenReturn(true);
        boolean result = employeeService.saveEmployee(employee);
        assertTrue(result);
    }
}

Output:

Test run: 1, Failures: 0, Errors: 0, Skipped: 0

Code Explanation:

- We introduced the EmployeeRepository class, which saves an employee to the database.

- EmployeeService is modified to use the EmployeeRepository to save an employee.

- In our test class EmployeeServiceTest, we mock the EmployeeRepository using the @Mock annotation.

- We also use @InjectMocks to inject the mocked EmployeeRepository into the EmployeeService.

- During the test, we define the behavior of the mock repository to return true when its save method is called.

- Finally, the saveEmployee method of EmployeeService is invoked, and we assert that its return value is true.

This setup allows us to test the service layer in isolation without involving the actual implementation of the repository.

5. Conclusion

By utilizing Mockito's @Mock annotation, we can quickly mock dependencies like repositories when testing our service layer. This approach ensures that our unit tests remain focused on the tested component and are not influenced by external factors or implementations. 

Advantages of Using @Mock:

Less Boilerplate: No need to explicitly create mock objects using Mockito.mock(). Just annotate the field, and you're set. 

Readability: Your test class becomes cleaner and easier to understand. The @Mock annotations clearly indicate which fields are mocks.

Related Mockito Annotations

Comments