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 the service layer is tested in isolation.
In this tutorial, we will demonstrate how to mock both 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)
<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 responsible for saving 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 easily mock dependencies like repositories when testing our service layer. This approach ensures that our unit tests remain focused on the component being tested 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
Comments
Post a Comment
Leave Comment