If you are new to Java testing, you might wonder: are JUnit 6 and Mockito competitors? Do I need both? When does Mockito replace JUnit 6? The answer is that they are not alternatives β they are complementary tools with completely different jobs. JUnit 6 runs your tests. Mockito creates the fake objects your tests use. This guide clarifies their distinct roles, shows how they integrate, and answers every question developers have about which tool does what.
What JUnit 6 Does
JUnit 6 is a test runner and test framework. Its responsibilities are:
- Discovering test classes and test methods on the classpath
- Managing the test lifecycle (
@BeforeEach,@AfterEach, etc.) - Executing test methods and reporting pass/fail/skip
- Providing assertion methods (
assertEquals,assertThrows,assertAll) - Supporting parameterized tests, dynamic tests, and parallel execution
- Integrating with build tools (Maven, Gradle) and IDEs
What Mockito Does
Mockito is a mocking framework. Its responsibilities are:
- Creating fake (mock) implementations of interfaces and classes
- Defining return values for method calls on mocks (stubbing)
- Verifying that methods were called with expected arguments
- Creating spies that wrap real objects with selective overrides
- Capturing method arguments for detailed inspection
Mockito does NOT run tests. JUnit 6 does NOT create mocks. They work together.
The Division of Labour
// This test uses BOTH JUnit 6 and Mockito β each doing its own job
import org.junit.jupiter.api.*; // JUnit 6: @Test, @BeforeEach, @DisplayName
import org.mockito.*; // Mockito: @Mock, @InjectMocks
import org.mockito.junit.jupiter.*; // Bridge: connects the two
import static org.junit.jupiter.api.Assertions.*; // JUnit 6: assertions
import static org.mockito.Mockito.*; // Mockito: when(), verify()
// JUnit 6 discovers and runs this class
@ExtendWith(MockitoExtension.class) // Mockito registers as a JUnit 6 extension
class OrderServiceTest {
// ---- Mockito's job: create fake dependencies ----
@Mock
private OrderRepository orderRepository; // fake repository
@Mock
private EmailService emailService; // fake email service
@InjectMocks
private OrderService orderService; // real class under test
// ---- JUnit 6's job: lifecycle management ----
@BeforeEach
void printTestStart() {
System.out.println("Test starting...");
}
// ---- JUnit 6's job: discover and execute this test ----
@Test
@DisplayName("Placing an order persists it and sends a confirmation email")
void placingOrderPersistsItAndSendsEmail() {
// ---- Mockito's job: define stub behaviour ----
Order savedOrder = new Order(1L, "[email protected]", 99.99, OrderStatus.CONFIRMED);
when(orderRepository.save(any(Order.class))).thenReturn(savedOrder);
// ---- The actual call under test ----
Order result = orderService.placeOrder("[email protected]", 99.99);
// ---- JUnit 6's job: assert the result ----
assertNotNull(result.getId(), "Order ID must be assigned");
assertEquals(OrderStatus.CONFIRMED, result.getStatus());
// ---- Mockito's job: verify interactions ----
verify(orderRepository, times(1)).save(any(Order.class));
verify(emailService, times(1)).sendConfirmation("[email protected]");
}
}