Mockito is a popular mocking framework for Java that allows you to create and configure mock objects for unit testing. It simplifies the process of testing by allowing you to simulate the behavior of complex dependencies. Below is a comprehensive guide to using Mockito for mocking in Java.
Key Features of Mockito
- Mock Creation: Easily create mock objects for interfaces and classes.
- Stubbing: Define the behavior of mock objects.
- Verification: Verify interactions with mock objects.
- Annotations: Use annotations to simplify mock creation and injection.
- Argument Matchers: Use matchers to define flexible stubbing and verification.
Setting Up Mockito
1. Add Dependencies
Add the following dependencies to your pom.xml
for a Maven project:
<dependencies>
<!-- Mockito Core -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.5.1</version>
<scope>test</scope>
</dependency>
<!-- JUnit (for testing) -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
</dependencies>
2. Import Mockito Classes
Import the necessary Mockito classes in your test class.
import static org.mockito.Mockito.*;
import org.mockito.Mock;
import org.mockito.InjectMocks;
import org.mockito.junit.jupiter.MockitoExtension;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
Basic Usage of Mockito
1. Create a Mock Object
Use Mockito.mock()
to create a mock object.
@Test
public void testMockCreation() {
List<String> mockedList = mock(List.class);
when(mockedList.get(0)).thenReturn("first");
assertEquals("first", mockedList.get(0));
}
2. Stubbing
Define the behavior of mock objects using when().thenReturn()
.
@Test
public void testStubbing() {
List<String> mockedList = mock(List.class);
when(mockedList.get(0)).thenReturn("first");
when(mockedList.get(1)).thenThrow(new RuntimeException("Exception"));
assertEquals("first", mockedList.get(0));
assertThrows(RuntimeException.class, () -> mockedList.get(1));
}
3. Verification
Verify interactions with mock objects using verify()
.
@Test
public void testVerification() {
List<String> mockedList = mock(List.class);
mockedList.add("one");
mockedList.add("two");
verify(mockedList).add("one");
verify(mockedList, times(2)).add(anyString());
}
Advanced Usage of Mockito
1. Annotations
Use annotations to simplify mock creation and injection.
@ExtendWith(MockitoExtension.class)
public class ExampleTest {
@Mock
private List<String> mockedList;
@InjectMocks
private SomeService someService;
@Test
public void testAnnotations() {
when(mockedList.get(0)).thenReturn("first");
assertEquals("first", someService.getList().get(0));
}
}
2. Argument Matchers
Use argument matchers for flexible stubbing and verification.
@Test
public void testArgumentMatchers() {
List<String> mockedList = mock(List.class);
when(mockedList.get(anyInt())).thenReturn("element");
assertEquals("element", mockedList.get(0));
assertEquals("element", mockedList.get(1));
verify(mockedList, times(2)).get(anyInt());
}
3. Spying
Use spy()
to create a partial mock that wraps a real object.
@Test
public void testSpying() {
List<String> realList = new ArrayList<>();
List<String> spyList = spy(realList);
spyList.add("one");
spyList.add("two");
verify(spyList).add("one");
verify(spyList).add("two");
assertEquals(2, spyList.size());
}
4. Capturing Arguments
Use ArgumentCaptor
to capture arguments for further assertions.
@Test
public void testArgumentCaptor() {
List<String> mockedList = mock(List.class);
mockedList.add("one");
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
verify(mockedList).add(captor.capture());
assertEquals("one", captor.getValue());
}
Best Practices
- Use Annotations: Simplify mock creation and injection with annotations.
- Keep Tests Simple: Focus on testing one behavior per test.
- Avoid Over-Mocking: Only mock necessary dependencies.
- Verify Interactions: Ensure that the expected interactions with mocks occur.
- Use Argument Matchers: Make stubbing and verification more flexible.
Resources
- Official Documentation: Mockito
- GitHub Repository: Mockito GitHub
- Tutorials and Examples: Mockito Tutorial