Introduction
Mockito is a popular mocking framework for Java, used to create and configure mock objects for unit testing. Mockito simplifies the process of creating test doubles and helps isolate the code being tested. This blog post will explore some of the key annotations provided by Mockito - @Mock
, @InjectMocks
, @Spy
, @Captor
, and @ExtendWith
.
Maven Dependencies
To use Mockito with JUnit 5, you need to include the following dependencies in your pom.xml
file:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.9.2</version>
<scope>test</scope>
</dependency>
Make sure to add these dependencies to your project's pom.xml
to ensure you have the latest versions of Mockito and JUnit.
@Mock
The @Mock
annotation is used to create and inject mock objects. It is commonly used to mock dependencies in unit tests.
Example
In this example, we will mock a List
object and verify that a method call is made.
import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.junit.jupiter.api.extension.ExtendWith;
@ExtendWith(MockitoExtension.class)
public class MockExampleTest {
@Mock
private List<String> mockList;
@Test
public void testMock() {
mockList.add("test");
verify(mockList).add("test");
}
}
Key Points:
@Mock
creates a mock instance of the class.verify
is used to verify that the methodadd
was called with the argument "test".
@InjectMocks
The @InjectMocks
annotation is used to inject mock objects into the class being tested. It helps to automatically inject all the mocks marked with @Mock
or @Spy
into the tested object.
Example
In this example, we will mock a Repository
and inject it into a Service
class. We will then verify that the Service
class behaves as expected when the Repository
is mocked.
import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.junit.jupiter.api.extension.ExtendWith;
class Service {
private final Repository repository;
public Service(Repository repository) {
this.repository = repository;
}
public String fetchData() {
return repository.getData();
}
}
interface Repository {
String getData();
}
@ExtendWith(MockitoExtension.class)
public class InjectMocksExampleTest {
@Mock
private Repository mockRepository;
@InjectMocks
private Service service;
@Test
public void testInjectMocks() {
when(mockRepository.getData()).thenReturn("mocked data");
String result = service.fetchData();
assertEquals("mocked data", result);
}
}
Key Points:
@InjectMocks
automatically injects mocks into the service instance.when
is used to define the behavior of the mock object.
@Spy
The @Spy
annotation is used to create a spy of a real object. Spies allow partial mocking, where you can mock some methods while using real implementations for others.
Example
In this example, we will create a spy for a User
class and mock its getName
method.
import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;
import org.junit.jupiter.api.extension.ExtendWith;
class User {
public String getName() {
return "Real Name";
}
}
@ExtendWith(MockitoExtension.class)
public class SpyExampleTest {
@Spy
private User user;
@Test
public void testSpy() {
when(user.getName()).thenReturn("Mocked Name");
String name = user.getName();
assertEquals("Mocked Name", name);
}
}
Key Points:
@Spy
creates a spy instance of the class.- Partial mocking is achieved by defining specific behaviors.
@Captor
The @Captor
annotation is used to create an argument captor, which captures argument values passed to mocked methods.
Example
In this example, we will use an argument captor to capture the argument passed to a mocked List
method.
import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import java.util.List;
@ExtendWith(MockitoExtension.class)
public class CaptorExampleTest {
@Mock
private List<String> mockList;
@Captor
private ArgumentCaptor<String> captor;
@Test
public void testCaptor() {
mockList.add("test");
verify(mockList).add(captor.capture());
assertEquals("test", captor.getValue());
}
}
Key Points:
@Captor
creates an argument captor instance.- Captured arguments can be asserted for verification.
@ExtendWith
The @ExtendWith
annotation is used to register extensions in JUnit 5. For Mockito, it is used to initialize Mockito annotations.
Example
In this example, we will use @ExtendWith
to initialize Mockito annotations for a test class.
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.junit.jupiter.api.extension.ExtendWith;
import java.util.List;
@ExtendWith(MockitoExtension.class)
public class ExtendWithExampleTest {
@Mock
private List<String> mockList;
@Test
public void testExtendWith() {
mockList.add("test");
verify(mockList).add("test");
}
}
Key Points:
@ExtendWith(MockitoExtension.class)
initializes Mockito annotations.- Ensures proper setup and teardown for Mockito in JUnit 5 tests.
Conclusion
Mockito annotations simplify the creation and management of mock objects in unit tests. By using @Mock
, @InjectMocks
, @Spy
, @Captor
, and @ExtendWith
, you can write more readable and maintainable test code. These annotations help you focus on testing the behavior of your code without worrying about the complexities of dependency management and object creation. Ensure you include the latest versions of Mockito and JUnit dependencies in your project to take advantage of the latest features and improvements.
Comments
Post a Comment
Leave Comment