Mockito

⭐ Interview Importance: MEDIUM
⏱️ Revision Time: 5 min

TL;DR

  • Mockito is the most popular mocking framework for Java.
  • It allows you to dynamically create fake objects (mocks) that mimic the behavior of real classes.
  • You use when(...).thenReturn(...) to program the mock’s behavior, and verify(...) to check if specific methods were called.

Concept

To write a Unit Test for an OrderService, you need to isolate it from the EmailService it depends on. You could write a custom class FakeEmailService implements EmailService by hand, but writing manual fake classes for every dependency in your app is exhausting.

Mockito uses Reflection and dynamic proxies to generate these fake objects on the fly.
You simply say EmailService mockEmail = mock(EmailService.class). Mockito creates an object that looks exactly like EmailService, but all its methods do absolutely nothing and return null (or 0). You then program exactly what you want it to do for the duration of the test.

Examples

import org.junit.jupiter.api.Test;
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;

class OrderServiceTest {

    @Test
    void testPlaceOrder() {
        // 1. Create Mocks for the dependencies
        InventoryService mockInventory = mock(InventoryService.class);
        EmailService mockEmail = mock(EmailService.class);
        
        // 2. Program the Mock behavior (Stubbing)
        // "When inventory is asked if Item #1 is in stock, return true."
        when(mockInventory.inStock(1)).thenReturn(true);
        
        // 3. Inject the mocks into the class we are actually testing
        OrderService service = new OrderService(mockInventory, mockEmail);
        
        // 4. ACT
        boolean success = service.placeOrder(1, "alice@test.com");
        
        // 5. ASSERT
        assertTrue(success);
        
        // 6. VERIFY interactions
        // Verify that the email service was actually called EXACTLY once with this email
        verify(mockEmail, times(1)).sendConfirmation("alice@test.com");
    }
}

Interview Questions

Q: What is the difference between when().thenReturn() and verify()?
A: - when().thenReturn() (Stubbing): Used in the “Arrange” phase. It programs the mock to return a specific piece of data when the class-under-test asks for it (e.g., faking a database read).

  • verify() (Verification): Used in the “Assert” phase. It checks the history of the mock to ensure the class-under-test actually called a specific method (e.g., verifying that the deleteUser() method was called on the database mock).

Q: How do the @Mock and @InjectMocks annotations work?
A: Instead of manually calling mock() and passing mocks into constructors, you can use Mockito annotations:

  • @Mock: Automatically creates a mock instance of the field.
  • @InjectMocks: Tells Mockito to instantiate this real class, and automatically inject all the @Mock fields into its constructor.
    Note: You must run MockitoAnnotations.openMocks(this) in your @BeforeEach or use the @ExtendWith(MockitoExtension.class) annotation on your class for these to work.