Mockito
Mockito
What is Mockito?
Mockito is a Java framework used to mock objects in unit tests.
It allows you to simulate dependencies (like services or repositories)
and focus only on the class being tested.
Goal: Test classes in isolation by simulating interactions with other
components.
Mockito focuses on behavior-driven development (BDD) by verifying
interactions between objects rather than their internal state.
Architecture Overview
Mockito's architecture revolves around three key components:
Compon Description
ent
Mock A fake object that mimics the behavior of real objects.
Created using mock().
Stubbin Defining what the mock should do when certain
g methods are called (e.g., when().thenReturn()).
Verificat Ensuring that certain methods on the mock were
ion called, and how many times (verify()).
How Mockito Works (Flow)
Create Mocks – Fake objects for classes or interfaces using
mock().
Stub Behavior – Define how the mock should behave using
when().thenReturn().
Call Methods – Execute methods on the class under test that
interact with the mocked object.
Verify Interactions – Check if the methods were called and if
they behaved as expected.
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.0.0</version>
<scope>test</scope>
</dependency>
Basic Concepts:
Mocking – Create fake objects.
Stubbing – Define behavior for mock methods.
Verification – Ensure certain methods were called.
Mockito's Benefits
Isolation: Tests are not dependent on other services or
databases.
Speed: Mocks avoid heavy operations, speeding up test
execution.
Flexibility: Simulates various conditions (like exceptions or
null responses).
Accuracy: Focuses solely on the logic within the class, making
tests precise.
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;
@SpringBootTest
class UserServiceTest {
@MockBean
private UserRepository userRepository; // Mock the repository bean
@Autowired
private MockMvc mockMvc; // Autowire MockMvc for making HTTP requests in
tests
@Test
void testAddUser() {
User user = new User("John Doe");
mockMvc.perform(post("/users").contentType(MediaType.APPLICATION_JSON).cont
ent(asJsonString(user)))
.andExpect(status().isOk());
}
}
@Mock
Purpose: Creates a mock object for a class or interface.
Use Case: Replace real dependencies with mocks.
Example:
@Mock
UserRepository userRepository;
@Spy
Purpose: Creates a partial mock – real methods are called unless stubbed.
Use Case: Use real object but override specific methods.
Example:
@Spy
List<String> list = new ArrayList<>();
@InjectMocks
Purpose: Injects mock or spy dependencies into the class being tested.
Use Case: Automatically injects mocks into the class under test.
Example:
@InjectMocks
UserService userService;
@Captor
Purpose: Captures arguments passed to mocked methods.
Use Case: Verifies arguments during method calls.
Example:
@Captor
ArgumentCaptor<User> captor;
@RunWith(MockitoJUnitRunner.class)
Purpose: Initializes mocks automatically.
Use Case: Ensures all mocks/spies are initialized before tests run.
Example:
@RunWith(MockitoJUnitRunner.class)
public class UserServiceTest {
}
@ExtendWith(MockitoExtension.class)
Purpose: JUnit 5 equivalent of @RunWith for initializing mocks.
Use Case: Initializes mocks in JUnit 5 tests.
Example:
@ExtendWith(MockitoExtension.class)
public class UserServiceTest {
}
Annotation Workflow
@ExtendWith(MockitoExtension.class)
public class UserServiceTest {
@Mock
UserRepository userRepository;
@InjectMocks
UserService userService;
@Captor
ArgumentCaptor<User> captor;
@Test
void testService() {
when(userRepository.findById(1)).thenReturn(new User(1, "John"));
userService.getUserName(1);
verify(userRepository).findById(captor.capture());
}
}