Mockito @ExtendWith Example

1. Overview

When developing applications, unit testing is an essential component to ensure functionality and reliability. Mockito is a prominent mocking framework for Java, and with JUnit 5, it has shifted to using the @ExtendWith annotation for integration. In this tutorial, we'll explore the usage of @ExtendWith with Mockito in the context of an Employee Management System.

Mockito @ExtendWith Overview

In JUnit 5, the @ExtendWith annotation is used to register custom extensions. For Mockito, this means using MockitoExtension.class with @ExtendWith to initialize mocks and leverage Mockito's features in JUnit 5 tests.

2. Development Steps

1. Set up the Maven dependencies for Mockito and JUnit 5.

2. Define the model, service, and repository classes for our Employee Management System.

3. Implement a test class using the @ExtendWith and @Mock annotations.

4. Run the test and analyze the results.

3. Dependencies (Mockito and JUnit 5)

<dependencies>
    <!-- JUnit 5 Dependency -->
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>5.10.0</version>
        <scope>test</scope>
    </dependency>
    <!-- Mockito Dependency -->
    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-junit-jupiter</artifactId>
        <version>5.6.0`</version>
        <scope>test</scope>
    </dependency>
</dependencies>

4. Code Program

// Model for our system
public class Employee {
    private Long id;
    private String name;
    // getters, setters, constructors
}
// Repository Interface
public interface EmployeeRepository {
    Employee findEmployeeById(Long id);
}
// Service layer
public class EmployeeService {
    private EmployeeRepository repository;
    public EmployeeService(EmployeeRepository repository) {
        this.repository = repository;
    }
    public Employee getEmployeeDetails(Long id) {
        return repository.findEmployeeById(id);
    }
}
// Test class
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;
@ExtendWith(MockitoExtension.class)
public class EmployeeServiceTest {
    @Mock
    private EmployeeRepository repository;
    @InjectMocks
    private EmployeeService service;
    @Test
    public void testGetEmployeeDetails() {
        Employee emp = new Employee();
        emp.setId(1L);
        emp.setName("John Doe");
        when(repository.findEmployeeById(1L)).thenReturn(emp);
        Employee result = service.getEmployeeDetails(1L);
        assertEquals(emp, result);
    }
}

Output:

The test testGetEmployeeDetails will pass, confirming that the service retrieves the correct employee details.

Code Explanation:

In the provided test:

1. We use the @ExtendWith(MockitoExtension.class) annotation at the class level to tell JUnit 5 to initialize mocks and prepare them for injection.

2. The @Mock annotation creates a mock implementation of the EmployeeRepository interface.

3. @InjectMocks is used to inject mock fields into the service instance.

4. In the test method testGetEmployeeDetails, we define the behavior of the mock (when(repository.findEmployeeById(1L)).thenReturn(emp);) and then execute the service method to be tested.

5. Finally, we assert that the returned employee matches the expected value.

5. Conclusion

Mockito's integration with JUnit 5 through the @ExtendWith annotation provides a seamless testing experience. It ensures mock initializations and injections are handled correctly, making unit tests concise and focused on the behavior being tested.

Related Mockito Annotations

Comments