Mockito mock objects library core API and implementation for comprehensive Java unit testing
—
This section covers Mockito's annotation-based approach to mock creation, dependency injection, and test class setup.
Create mock objects automatically from annotated fields.
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@interface Mock {
Answers answer() default Answers.RETURNS_DEFAULTS;
String name() default "";
Class<?>[] extraInterfaces() default {};
boolean serializable() default false;
Strictness strictness() default Strictness.STRICT_STUBS;
String mockMaker() default "";
boolean stubOnly() default false;
boolean withoutAnnotations() default false;
}Usage Examples:
class UserServiceTest {
@Mock
private UserRepository userRepository;
@Mock(answer = Answers.RETURNS_SMART_NULLS)
private EmailService emailService;
@Mock(name = "authMock", strictness = Strictness.LENIENT)
private AuthService authService;
@Mock(extraInterfaces = {Serializable.class, Cloneable.class})
private DataProcessor dataProcessor;
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
}
}Create spy objects that wrap real instances or classes.
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@interface SpyUsage Examples:
class OrderServiceTest {
// Spy on existing instance
@Spy
private List<String> spiedList = new ArrayList<>();
// Spy on class (calls default constructor)
@Spy
private UserService userService;
// Spy with initialization
@Spy
private Calculator calculator = new Calculator();
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
}
@Test
void testSpyBehavior() {
// Real method called
spiedList.add("real item");
assertEquals(1, spiedList.size());
// Stubbed behavior
when(spiedList.size()).thenReturn(100);
assertEquals(100, spiedList.size());
}
}Automatically inject mocks into the tested object.
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface InjectMocksUsage Examples:
class UserServiceTest {
@Mock
private UserRepository userRepository;
@Mock
private EmailService emailService;
@Mock
private ValidationService validationService;
@InjectMocks
private UserService userService; // Mocks injected here
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
}
@Test
void testUserCreation() {
// Mocks are already injected into userService
when(validationService.isValidEmail(anyString())).thenReturn(true);
when(userRepository.save(any(User.class))).thenReturn(savedUser);
User result = userService.createUser("john", "john@example.com");
verify(validationService).isValidEmail("john@example.com");
verify(userRepository).save(any(User.class));
assertNotNull(result);
}
}Create ArgumentCaptor instances automatically.
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface CaptorUsage Examples:
class EventServiceTest {
@Mock
private EventPublisher eventPublisher;
@Captor
private ArgumentCaptor<Event> eventCaptor;
@Captor
private ArgumentCaptor<String> stringCaptor;
@InjectMocks
private OrderService orderService;
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
}
@Test
void testEventPublishing() {
orderService.createOrder("item1", "item2");
// Capture published events
verify(eventPublisher, times(2)).publish(eventCaptor.capture());
List<Event> events = eventCaptor.getAllValues();
assertEquals(2, events.size());
assertEquals("ORDER_CREATED", events.get(0).getType());
}
}Mark classes that should not be mocked.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface DoNotMock {
String reason() default "";
}Usage Examples:
@DoNotMock(reason = "Use real instance or create a fake")
public class ValueObject {
private final String value;
public ValueObject(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
// In tests, Mockito will warn if you try to mock this
class SomeTest {
@Test
void testWithValueObject() {
// This will generate a warning
// ValueObject mock = mock(ValueObject.class);
// Use real instance instead
ValueObject realObject = new ValueObject("test");
}
}Initialize annotated mocks in test classes.
public static AutoCloseable openMocks(Object testClass)
public static void initMocks(Object testClass) // DeprecatedUsage Examples:
class ModernTestSetup {
@Mock
private UserService userService;
private AutoCloseable closeable;
@BeforeEach
void setUp() {
closeable = MockitoAnnotations.openMocks(this);
}
@AfterEach
void tearDown() throws Exception {
closeable.close();
}
}
// Alternative with try-with-resources
class AlternativeSetup {
@Test
void testWithAutoClose() throws Exception {
try (AutoCloseable closeable = MockitoAnnotations.openMocks(this)) {
// Test code here
}
}
}Mockito tries constructor injection first.
// Service class with constructor
public class OrderService {
private final PaymentService paymentService;
private final InventoryService inventoryService;
public OrderService(PaymentService paymentService,
InventoryService inventoryService) {
this.paymentService = paymentService;
this.inventoryService = inventoryService;
}
}
// Test class
class OrderServiceTest {
@Mock private PaymentService paymentService;
@Mock private InventoryService inventoryService;
@InjectMocks private OrderService orderService; // Constructor injection
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
}
}Falls back to setter injection if constructor injection isn't possible.
public class UserService {
private EmailService emailService;
private ValidationService validationService;
public void setEmailService(EmailService emailService) {
this.emailService = emailService;
}
public void setValidationService(ValidationService validationService) {
this.validationService = validationService;
}
}
// Mocks injected via setters
class UserServiceTest {
@Mock private EmailService emailService;
@Mock private ValidationService validationService;
@InjectMocks private UserService userService; // Setter injection
}Last resort: direct field injection.
public class ReportService {
@Autowired
private DataService dataService; // Private field
private EmailService emailService; // No setter
}
// Field injection used
class ReportServiceTest {
@Mock private DataService dataService;
@Mock private EmailService emailService;
@InjectMocks private ReportService reportService; // Field injection
}Use MockitoExtension for automatic setup.
@ExtendWith(MockitoExtension.class)Usage Example:
@ExtendWith(MockitoExtension.class)
class JUnit5Test {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
// No @BeforeEach needed - extension handles setup
@Test
void testUserCreation() {
when(userRepository.save(any())).thenReturn(savedUser);
User result = userService.createUser("test");
verify(userRepository).save(any(User.class));
}
}Legacy JUnit 4 integration options.
@RunWith(MockitoJUnitRunner.class)
@RunWith(MockitoJUnitRunner.Strict.class)
public static MockitoRule rule()Usage Examples:
// JUnit 4 Runner
@RunWith(MockitoJUnitRunner.class)
public class JUnit4RunnerTest {
@Mock private UserService userService;
@InjectMocks private OrderService orderService;
// No setup needed
}
// JUnit 4 Rule (more flexible)
public class JUnit4RuleTest {
@Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();
@Mock private UserService userService;
@InjectMocks private OrderService orderService;
}
// Strict rule (fails on unused stubs)
public class StrictRuleTest {
@Rule
public MockitoRule mockitoRule = MockitoJUnit.rule()
.strictness(Strictness.STRICT_STUBS);
@Mock private UserService userService;
}Annotations are better for:
Manual creation is better for:
Comparison Example:
class ComparisonExample {
// Annotation approach
@Mock private UserRepository userRepository;
@InjectMocks private UserService userService;
@BeforeEach
void annotationSetup() {
MockitoAnnotations.openMocks(this);
}
@Test
void annotationTest() {
// Test with injected mocks
}
// Manual approach
@Test
void manualTest() {
UserRepository mockRepo = mock(UserRepository.class);
UserService service = new UserService(mockRepo);
// Test with manually created mocks
}
// Mixed approach
@Test
void mixedTest() {
// Some mocks from annotations
// Some created manually for specific needs
PaymentService specialMock = mock(PaymentService.class,
withSettings().strictness(Strictness.LENIENT));
}
}Install with Tessl CLI
npx tessl i tessl/maven-org-mockito--mockito-core