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

junit-integration.mddocs/

JUnit Integration

Mockito provides seamless integration with JUnit testing framework through runners and rules, enabling automatic mock initialization and enhanced debugging capabilities.

JUnit Runners

MockitoJUnitRunner

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

VerboseMockitoJUnitRunner

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:

  • Detailed mock interaction logging
  • Enhanced error messages with stack traces
  • Better debugging information for test failures
  • Helps identify unused stubs and interactions

ConsoleSpammingMockitoJUnitRunner

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

JUnit Rules

MockitoRule

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

Rule with Custom Configuration

public class UserServiceTest {
    
    @Rule
    public MockitoRule mockitoRule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);
    
    // Strict mode helps catch unused stubs and other issues
}

Integration Patterns

Combining with Other Runners

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

JUnit 5 Integration

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

Test Lifecycle Integration

Manual Initialization

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

Base Test Class Pattern

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

Debugging and Troubleshooting

Validation

Enable automatic validation of Mockito usage:

@After
public void validateMockitoUsage() {
    Mockito.validateMockitoUsage();
}

What it catches:

  • Unfinished stubbing
  • Unused stubs
  • Unnecessary stubs
  • Invalid use of matchers

Verbose Output Example

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

Console Output Configuration

@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...
    }
}

Best Practices

Choose the Right Integration Method

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

Test Organization

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

Error Handling

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

Integration Testing

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

Common Integration Issues

Runner Conflicts

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

Initialization Order

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

Forgotten Initialization

// 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

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