A comprehensive Java mocking framework that enables developers to create test doubles for unit testing.
—
Mockito provides seamless integration with JUnit testing framework through runners and rules, enabling automatic mock initialization and enhanced debugging capabilities.
Automatically initializes mocks without requiring explicit setup:
public class MockitoJUnitRunner extends Runner { }Usage:
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class UserServiceTest {
@Mock
private UserRepository userRepository;
@Mock
private EmailService emailService;
@InjectMocks
private UserService userService;
// No need for MockitoAnnotations.initMocks(this)
@Test
public void testUserCreation() {
when(userRepository.save(any(User.class))).thenReturn(user);
User result = userService.createUser("John", "john@example.com");
verify(emailService).sendWelcomeEmail(user);
assertEquals("John", result.getName());
}
}Enhanced debugging with detailed output:
public class VerboseMockitoJUnitRunner extends MockitoJUnitRunner { }Usage:
@RunWith(VerboseMockitoJUnitRunner.class)
public class UserServiceTest {
@Mock private UserRepository userRepository;
@InjectMocks private UserService userService;
@Test
public void testWithVerboseOutput() {
// Test implementation
// Runner will provide detailed output for debugging
}
}Benefits of Verbose Runner:
Prints warnings and hints to console:
public class ConsoleSpammingMockitoJUnitRunner extends MockitoJUnitRunner { }Usage:
@RunWith(ConsoleSpammingMockitoJUnitRunner.class)
public class UserServiceTest {
// Prints warnings about unused stubs, potential issues, etc.
}Alternative to runners when you can't use @RunWith:
public interface MockitoRule extends TestRule { }
public class MockitoJUnit {
public static MockitoRule rule();
}Basic Usage:
import org.junit.Rule;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
public class UserServiceTest {
@Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@Test
public void testUserService() {
// Mocks are automatically initialized
when(userRepository.findById(1)).thenReturn(user);
User result = userService.getUser(1);
assertEquals(user, result);
}
}public class UserServiceTest {
@Rule
public MockitoRule mockitoRule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);
// Strict mode helps catch unused stubs and other issues
}When you need multiple runners, use rules instead:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TestConfig.class)
public class IntegrationTest {
@Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();
@Autowired
private ApplicationService applicationService;
@Mock
private ExternalService externalService;
@Test
public void testIntegration() {
// Mix Spring integration with Mockito mocks
}
}For JUnit 5, use the MockitoExtension:
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@Test
void testUserCreation() {
// Test implementation
}
}When you can't use runners or rules:
public class UserServiceTest {
@Mock private UserRepository userRepository;
@InjectMocks private UserService userService;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
@After
public void tearDown() {
// Optional cleanup
validateMockitoUsage();
}
@Test
public void testUser() {
// Test implementation
}
}public abstract class BaseMockitoTest {
@Before
public void setUpMocks() {
MockitoAnnotations.initMocks(this);
}
@After
public void validateMocks() {
validateMockitoUsage();
}
}
public class UserServiceTest extends BaseMockitoTest {
@Mock private UserRepository userRepository;
@InjectMocks private UserService userService;
@Test
public void testUser() {
// Test implementation inherits mock setup
}
}Enable automatic validation of Mockito usage:
@After
public void validateMockitoUsage() {
Mockito.validateMockitoUsage();
}What it catches:
@RunWith(VerboseMockitoJUnitRunner.class)
public class DebuggingTest {
@Mock private Service service;
@Test
public void testWithDebugging() {
when(service.process("input")).thenReturn("output");
when(service.process("unused")).thenReturn("never_used"); // Unused stub
String result = service.process("input");
// VerboseMockitoJUnitRunner will report:
// - Used stubs
// - Unused stubs (potential issues)
// - All interactions
}
}@RunWith(ConsoleSpammingMockitoJUnitRunner.class)
public class ConsoleOutputTest {
@Mock private Service service;
@Test
public void testWithConsoleOutput() {
// Console will show:
// [MockitoHint] You have unused stubbings in this test...
// [MockitoHint] Consider removing unnecessary stubbings...
}
}// Use MockitoJUnitRunner for simple cases
@RunWith(MockitoJUnitRunner.class)
public class SimpleTest { }
// Use MockitoRule when combining with other runners
@RunWith(SpringRunner.class)
public class SpringIntegrationTest {
@Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
}
// Use manual initialization for maximum control
public class ComplexTest {
@Before public void setUp() { MockitoAnnotations.initMocks(this); }
}@RunWith(MockitoJUnitRunner.class)
public class UserServiceTest {
// Group related mocks
@Mock private UserRepository userRepository;
@Mock private UserValidator userValidator;
@Mock private UserNotificationService notificationService;
// Service under test
@InjectMocks private UserService userService;
// Test data setup
private User testUser;
@Before
public void setUp() {
testUser = new User("John", "john@example.com");
}
@Test
public void shouldCreateValidUser() {
// Given
when(userValidator.isValid(testUser)).thenReturn(true);
when(userRepository.save(testUser)).thenReturn(testUser);
// When
User result = userService.createUser(testUser);
// Then
assertEquals(testUser, result);
verify(notificationService).sendWelcomeEmail(testUser);
}
}@RunWith(VerboseMockitoJUnitRunner.class)
public class ErrorHandlingTest {
@Mock private ErrorProneService service;
@Test
public void testErrorScenarios() {
// Setup error conditions
when(service.process(anyString())).thenThrow(ProcessingException.class);
// Test error handling
assertThrows(ProcessingException.class, () -> {
service.process("test");
});
// VerboseMockitoJUnitRunner helps debug any issues
}
}@RunWith(SpringRunner.class)
@SpringBootTest
public class IntegrationTest {
@Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();
@Autowired
private UserController userController;
@MockBean // Spring Boot's mock annotation
private UserService userService;
@Mock // Mockito's mock annotation
private ExternalApiClient apiClient;
@Test
public void testControllerIntegration() {
// Mix Spring integration testing with Mockito mocks
when(userService.findUser(1)).thenReturn(user);
ResponseEntity<User> response = userController.getUser(1);
assertEquals(HttpStatus.OK, response.getStatusCode());
assertEquals(user, response.getBody());
}
}// PROBLEM: Can't use multiple runners
@RunWith(MockitoJUnitRunner.class)
@RunWith(SpringRunner.class) // Compilation error
public class ConflictTest { }
// SOLUTION: Use rule instead
@RunWith(SpringRunner.class)
public class SolutionTest {
@Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
}// PROBLEM: Wrong initialization order
public class InitializationProblem extends BaseTest {
public InitializationProblem() {
MockitoAnnotations.initMocks(this); // Too early!
}
}
// SOLUTION: Use @Before or runner
@RunWith(MockitoJUnitRunner.class)
public class InitializationSolution extends BaseTest {
// Automatic initialization at right time
}// PROBLEM: Mocks not initialized
public class ForgottenInitTest {
@Mock private Service service; // Will be null!
@Test
public void test() {
service.doSomething(); // NullPointerException
}
}
// SOLUTION: Add initialization
@RunWith(MockitoJUnitRunner.class)
public class ProperInitTest {
@Mock private Service service; // Properly initialized
}Install with Tessl CLI
npx tessl i tessl/maven-org-mockito--mockito-all