CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-mockito--mockito-core

Mockito mock objects library core API and implementation for comprehensive Java unit testing

Pending
Overview
Eval results
Files

annotations.mddocs/

Annotations and Test Setup

This section covers Mockito's annotation-based approach to mock creation, dependency injection, and test class setup.

Core Annotations

@Mock Annotation

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);
    }
}

@Spy Annotation

Create spy objects that wrap real instances or classes.

@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@interface Spy

Usage 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());
    }
}

@InjectMocks Annotation

Automatically inject mocks into the tested object.

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface InjectMocks

Usage 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);
    }
}

@Captor Annotation

Create ArgumentCaptor instances automatically.

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)  
@interface Captor

Usage 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());
    }
}

Advanced Annotations

@DoNotMock Annotation

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");
    }
}

Mock Initialization

MockitoAnnotations Class

Initialize annotated mocks in test classes.

public static AutoCloseable openMocks(Object testClass)
public static void initMocks(Object testClass) // Deprecated

Usage 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
        }
    }
}

Injection Strategies

Constructor Injection

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);
    }
}

Setter Injection

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
}

Field 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
}

JUnit Integration

JUnit 5 Extension

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));
    }
}

JUnit 4 Runner and Rule

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;
}

Manual Mock Creation vs Annotations

When to Use Each Approach

Annotations are better for:

  • Standard test setup
  • Consistent mock configuration
  • Automatic dependency injection
  • Integration with test frameworks

Manual creation is better for:

  • Dynamic mock creation
  • Test-specific configuration
  • Complex mock setup
  • Conditional mock creation

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

docs

additional-answers.md

additional-matchers.md

advanced-features.md

annotations.md

argument-matching.md

bdd-testing.md

index.md

mock-creation.md

static-mocking.md

stubbing.md

verification.md

tile.json