Labs ICT
โญ Pro Login

Mocking with Mockito

When testing, you often do not want to depend on real databases, external services, or complex objects. Mocking lets you create fake versions of these dependencies so you can test your code in isolation. Mockito is the most popular mocking library for Java, and it integrates seamlessly with JUnit 5.

Adding Mockito


<!-- Maven -->
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>junit-jupiter-mockito</artifactId>
    <version>5.11.0</version>
    <scope>test</scope>
</dependency>

<!-- Or for the Mockito BOM -->
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>5.11.0</version>
    <scope>test</scope>
</dependency>

// Gradle
testImplementation 'org.mockito:mockito-core:5.11.0'
    

Basic Mocking


import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)
class OrderServiceTest {

    @Mock
    private EmailService emailService;

    @Mock
    private PaymentGateway paymentGateway;

    @Test
    void shouldPlaceOrder() {
        // Arrange
        OrderService service = new OrderService(emailService, paymentGateway);
        Order order = new Order("user@example.com", 99.99);

        when(paymentGateway.charge(99.99)).thenReturn(true);
        doNothing().when(emailService).sendConfirmation(anyString());

        // Act
        service.placeOrder(order);

        // Assert
        verify(paymentGateway).charge(99.99);
        verify(emailService).sendConfirmation("user@example.com");
    }
}
    

Creating Mocks with Mockito.mock()


class MockCreationDemo {

    @Test
    void mockCreation() {
        // Method 1: mock() method
        List<String> mockList = mock(List.class);

        // Method 2: @Mock annotation (with @ExtendWith)
        // (shown above)

        // Use the mock
        when(mockList.size()).thenReturn(5);
        assertEquals(5, mockList.size());
    }
}
    

Stubbing Methods

Stubbing means telling the mock what to return when certain methods are called:


@Test
void stubbingDemo() {
    List<String> mockList = mock(List.class);

    // Return a specific value
    when(mockList.get(0)).thenReturn("first");
    when(mockList.get(1)).thenReturn("second");

    // Return different values on successive calls
    when(mockList.size())
        .thenReturn(3)
        .thenReturn(2)
        .thenReturn(1);

    assertEquals("first", mockList.get(0));
    assertEquals("second", mockList.get(1));

    assertEquals(3, mockList.size());
    assertEquals(2, mockList.size());
    assertEquals(1, mockList.size());

    // Throw an exception
    when(mockList.get(99)).thenThrow(
        new IndexOutOfBoundsException("Index 99 out of bounds")
    );

    assertThrows(IndexOutOfBoundsException.class,
        () -> mockList.get(99));
}
    

@InjectMocks

When your class under test has dependencies, use @InjectMocks to automatically inject mocked dependencies:


@ExtendWith(MockitoExtension.class)
class UserServiceTest {

    @Mock
    private UserRepository userRepository;

    @Mock
    private EmailService emailService;

    @InjectMocks
    private UserService userService; // Dependencies injected automatically

    @Test
    void shouldRegisterUser() {
        User user = new User("john@example.com");

        when(userRepository.save(any(User.class))).thenReturn(user);
        doNothing().when(emailService).sendWelcome(anyString());

        userService.register(user);

        verify(userRepository).save(user);
        verify(emailService).sendWelcome("john@example.com");
    }
}
    

Mock vs Spy


// Mock: completely fake, all methods return defaults
List<String> mock = mock(List.class);
mock.size(); // returns 0 (default for int)
mock.isEmpty(); // returns true (default for boolean)

// Spy: wraps real object, calls real methods unless stubbed
List<String> realList = new ArrayList<>();
realList.add("hello");
List<String> spy = spy(realList);
spy.size(); // returns 1 (real method called!)
when(spy.isEmpty()).thenReturn(true);
spy.isEmpty(); // returns true (stubbed)
    

When to Mock

  • External services - APIs, payment gateways, email services
  • Database access - Repository classes, data mappers
  • File system operations - File readers, writers
  • Time-dependent code - Mock the clock for deterministic tests
  • Complex objects - Objects that are expensive to create

๐Ÿงช Quick Quiz

Which Mockito method creates a mock object?