CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-mockito--mockito-all

A comprehensive Java mocking framework that enables developers to create test doubles for unit testing.

Pending
Overview
Eval results
Files

annotations.mddocs/

Annotation-Based Testing

Mockito provides annotations to streamline test setup by automatically creating mocks, spies, and argument captors. This reduces boilerplate code and makes tests more readable.

Core Annotations

@Mock Annotation

Mark fields as mocks for automatic creation:

@Target(FIELD)
@Retention(RUNTIME)
@Documented
public @interface Mock {
    Answers answer() default Answers.RETURNS_DEFAULTS;
    String name() default "";
    Class<?>[] extraInterfaces() default {};
    boolean serializable() default false;
}

Usage Examples:

public class UserServiceTest {
    @Mock
    private UserRepository userRepository;
    
    @Mock(name = "emailService")
    private EmailService emailService;
    
    @Mock(answer = Answers.RETURNS_SMART_NULLS)
    private ConfigService configService;
    
    @Mock(extraInterfaces = {Serializable.class, Cloneable.class})
    private DataProcessor processor;
    
    @Mock(serializable = true)
    private CacheService cacheService;
    
    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }
}

@Spy Annotation

Mark fields as spies for wrapping real objects:

@Retention(RUNTIME)
@Target(FIELD)
@Documented
public @interface Spy { }

Usage Examples:

public class ServiceTest {
    // Spy with explicit instance
    @Spy
    private List<String> spyList = new ArrayList<>();
    
    // Spy with default constructor (Mockito creates instance)
    @Spy
    private UserService userService;
    
    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }
    
    @Test
    public void testSpyBehavior() {
        // Real method is called
        spyList.add("item");
        assertEquals(1, spyList.size());
        
        // Can stub methods
        doReturn(100).when(spyList).size();
        assertEquals(100, spyList.size());
    }
}

@InjectMocks Annotation

Mark fields where mocks should be injected:

@Documented
@Target(FIELD)
@Retention(RUNTIME)
public @interface InjectMocks { }

Usage Examples:

public class UserServiceTest {
    @Mock
    private UserRepository repository;
    
    @Mock
    private EmailService emailService;
    
    @Mock
    private ValidationService validationService;
    
    @InjectMocks
    private UserService userService; // Mocks will be injected here
    
    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }
    
    @Test
    public void testUserCreation() {
        User user = new User("John", "john@example.com");
        when(repository.save(any(User.class))).thenReturn(user);
        
        User result = userService.createUser("John", "john@example.com");
        
        assertEquals("John", result.getName());
        verify(emailService).sendWelcomeEmail(user);
    }
}

@Captor Annotation

Mark fields as argument captors:

@Retention(RUNTIME)
@Target(FIELD)
@Documented
public @interface Captor { }

Usage Examples:

public class EmailServiceTest {
    @Mock
    private EmailProvider emailProvider;
    
    @Captor
    private ArgumentCaptor<EmailMessage> messageCaptor;
    
    @Captor
    private ArgumentCaptor<String> stringCaptor;
    
    @InjectMocks
    private EmailService emailService;
    
    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }
    
    @Test
    public void testEmailSending() {
        emailService.sendWelcomeEmail("user@example.com", "John");
        
        verify(emailProvider).send(messageCaptor.capture());
        EmailMessage capturedMessage = messageCaptor.getValue();
        
        assertEquals("user@example.com", capturedMessage.getTo());
        assertEquals("Welcome John!", capturedMessage.getSubject());
    }
}

Initialization

MockitoAnnotations.initMocks()

Initialize all annotated fields:

public class MockitoAnnotations {
    public static void initMocks(Object testClass);
}

Usage Patterns:

// In @Before method
@Before
public void setUp() {
    MockitoAnnotations.initMocks(this);
}

// In test constructor
public MyTest() {
    MockitoAnnotations.initMocks(this);
}

// In @BeforeEach (JUnit 5)
@BeforeEach
void setUp() {
    MockitoAnnotations.initMocks(this);
}

Dependency Injection Strategies

Constructor Injection

Mockito tries constructor injection first (biggest constructor):

public class UserService {
    private final UserRepository repository;
    private final EmailService emailService;
    
    // Mockito will use this constructor
    public UserService(UserRepository repository, EmailService emailService) {
        this.repository = repository;
        this.emailService = emailService;
    }
}

public class UserServiceTest {
    @Mock private UserRepository repository;
    @Mock private EmailService emailService;
    @InjectMocks private UserService userService;
    
    // Mocks will be injected via constructor
}

Setter Injection

If constructor injection fails, Mockito tries setter injection:

public class UserService {
    private UserRepository repository;
    private EmailService emailService;
    
    public void setRepository(UserRepository repository) {
        this.repository = repository;
    }
    
    public void setEmailService(EmailService emailService) {
        this.emailService = emailService;
    }
}

Field Injection

If setter injection fails, Mockito tries field injection:

public class UserService {
    private UserRepository repository;    // Will be injected
    private EmailService emailService;    // Will be injected
}

JUnit Integration

MockitoJUnitRunner

Automatically initializes mocks without explicit setup:

public class MockitoJUnitRunner extends Runner { }

Usage:

@RunWith(MockitoJUnitRunner.class)
public class UserServiceTest {
    @Mock
    private UserRepository repository;
    
    @InjectMocks
    private UserService userService;
    
    // No need for MockitoAnnotations.initMocks()
    
    @Test
    public void testUser() {
        // Test implementation
    }
}

Verbose Runner

Enhanced debugging with verbose output:

public class VerboseMockitoJUnitRunner extends MockitoJUnitRunner { }

Usage:

@RunWith(VerboseMockitoJUnitRunner.class)
public class UserServiceTest {
    // Provides detailed output for debugging
}

MockitoRule (Alternative to Runner)

Use when you can't use MockitoJUnitRunner:

public interface MockitoRule extends TestRule { }

public class MockitoJUnit {
    public static MockitoRule rule();
}

Usage:

public class UserServiceTest {
    @Rule
    public MockitoRule mockitoRule = MockitoJUnit.rule();
    
    @Mock
    private UserRepository repository;
    
    @InjectMocks
    private UserService userService;
}

Best Practices

Field vs Method Initialization

// Good - field initialization for simple cases
@Spy
private List<String> list = new ArrayList<>();

// Good - method initialization for complex setup
@Spy
private ComplexService service;

@Before
public void setUp() {
    service = new ComplexService(config, dependencies);
    MockitoAnnotations.initMocks(this);
}

Naming Conventions

// Good - descriptive names
@Mock(name = "userRepository")
private UserRepository userRepository;

@Mock(name = "emailService")
private EmailService emailService;

// Good - match field names with dependencies
public class UserService {
    private UserRepository userRepository; // Matches mock field name
    private EmailService emailService;     // Matches mock field name
}

Mock Configuration

// Good - appropriate answers for test scenarios
@Mock(answer = Answers.RETURNS_SMART_NULLS)
private ComplexService complexService;

@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private FluentApi fluentApi;

// Good - extra interfaces when needed
@Mock(extraInterfaces = {Serializable.class})
private DataTransferObject dto;

Injection Best Practices

public class ServiceTest {
    @Mock private Dependency1 dep1;
    @Mock private Dependency2 dep2;
    
    @InjectMocks private Service service;
    
    @Test
    public void testServiceBehavior() {
        // Configure mocks
        when(dep1.getData()).thenReturn("data");
        
        // Test service that uses injected mocks
        String result = service.processData();
        
        // Verify interactions
        verify(dep1).getData();
        assertEquals("processed: data", result);
    }
}

Common Pitfalls

Initialization Order

// WRONG - calling initMocks() in constructor of superclass
public class BaseTest {
    public BaseTest() {
        MockitoAnnotations.initMocks(this); // Subclass fields not yet initialized
    }
}

// CORRECT - use @Before or test runner
@RunWith(MockitoJUnitRunner.class)
public class MyTest extends BaseTest {
    @Mock private Service service;
}

Spy Limitations

// Mockito cannot instantiate these:
@Spy private InnerClass inner;        // Inner classes
@Spy private AbstractClass abs;       // Abstract classes  
@Spy private Interface intf;          // Interfaces
@Spy private final FinalClass fin;    // Final fields
@Spy private static StaticClass stat; // Static fields

Injection Failures

// Will fail injection - no matching constructor/setter/field
public class Service {
    public Service(String config, int port) { } // No default constructor
    // No setters or matching fields
}

public class Test {
    @Mock private UserRepository repo;  // Type doesn't match constructor params
    @InjectMocks private Service service; // Injection will fail silently
}

Install with Tessl CLI

npx tessl i tessl/maven-org-mockito--mockito-all

docs

annotations.md

argument-capturing.md

bdd-testing.md

index.md

junit-integration.md

matchers.md

mock-creation.md

stubbing.md

verification.md

tile.json