Mockito tutorial

Mockito Quick Guide (with PowerMock) — Practical Examples for JUnit 5

Mockito is the most popular Java mocking framework used in unit testing to simulate dependencies (DB, REST clients, external services) so you can test logic fast and reliably.

Why Mockito?

  • ✅ Test business logic without real dependencies
  • ✅ Faster tests (no network/DB)
  • ✅ Cleaner, more maintainable unit tests
  • ✅ Verify behavior (method calls, arguments)

Add Dependencies (Maven)

Mockito + JUnit 5 (recommended modern setup)

<dependency>
  <groupId>org.junit.jupiter</groupId>
  <artifactId>junit-jupiter</artifactId>
  <version>5.10.2</version>
  <scope>test</scope>
</dependency>

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

<dependency>
  <groupId>org.mockito</groupId>
  <artifactId>mockito-core</artifactId>
  <version>5.11.0</version>
  <scope>test</scope>
</dependency>

Core Mockito Concepts

1) Create a Mock

import static org.mockito.Mockito.*;

List<String> list = mock(List.class);
when(list.size()).thenReturn(10);

assertEquals(10, list.size());

2) @Mock and @InjectMocks (Most Common)

@ExtendWith(MockitoExtension.class)
class OrderServiceTest {

  @Mock PaymentGateway paymentGateway;
  @Mock OrderRepo orderRepo;

  @InjectMocks OrderService orderService;

  @Test
  void shouldPlaceOrder() {
    when(paymentGateway.pay(anyDouble())).thenReturn(true);

    boolean ok = orderService.placeOrder(200.0);

    assertTrue(ok);
    verify(orderRepo).save(any(Order.class));
  }
}

What it means

  • @Mock creates fake dependencies
  • @InjectMocks creates your service and injects mocks into it
  • verify() checks interactions

Stubbing Cheat Sheet (Most Used)

Return a value

when(repo.findById(1L)).thenReturn(Optional.of(new User()));

Throw an exception

when(repo.findById(99L)).thenThrow(new RuntimeException("Not found"));

For void methods

doNothing().when(audit).log(anyString());
doThrow(new IllegalStateException()).when(audit).log("BAD");

Argument Matchers (any(), eq(), argThat())

when(client.call(eq("IN"), anyInt())).thenReturn("OK");

Rule: If you use a matcher (any(), eq()), use matchers for all args in that call.


Verify Calls (Behavior Testing)

verify(service).process("A");
verify(service, times(2)).process("A");
verify(service, never()).process("X");
verifyNoInteractions(unusedDependency);

Capturing Arguments (ArgumentCaptor)

When you want to assert what was passed into a dependency:

ArgumentCaptor<Order> captor = ArgumentCaptor.forClass(Order.class);

verify(orderRepo).save(captor.capture());
assertEquals(200.0, captor.getValue().amount());

Spy vs Mock (Very Important)

Mock

  • Everything is fake by default

Spy

  • Wraps a real object, but you can stub specific methods
List<String> real = new ArrayList<>();
List<String> spyList = spy(real);

doReturn(100).when(spyList).size(); // safer than when(...).thenReturn(...)

PowerMock / PowerMockito (Legacy Use Cases)

✅ Use PowerMock only when you cannot refactor (legacy static calls, constructors, private methods).
⚠️ PowerMock has limited compatibility with modern JUnit/Mockito versions and is generally not recommended for new projects.

When PowerMock is Used

  • Mocking static methods
  • Mocking new constructor calls
  • Mocking private methods
  • Mocking final classes (older setups)

PowerMock Dependencies (Common JUnit 4 Setup)

PowerMock works best with JUnit 4 in many projects.

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.13.2</version>
  <scope>test</scope>
</dependency>

<dependency>
  <groupId>org.mockito</groupId>
  <artifactId>mockito-core</artifactId>
  <version>4.11.0</version>
  <scope>test</scope>
</dependency>

<dependency>
  <groupId>org.powermock</groupId>
  <artifactId>powermock-module-junit4</artifactId>
  <version>2.0.9</version>
  <scope>test</scope>
</dependency>

<dependency>
  <groupId>org.powermock</groupId>
  <artifactId>powermock-api-mockito2</artifactId>
  <version>2.0.9</version>
  <scope>test</scope>
</dependency>

Mock Static Method (PowerMockito)

@RunWith(PowerMockRunner.class)
@PrepareForTest({DateUtil.class})
public class BillingServiceTest {

  @Test
  public void shouldMockStatic() {
    PowerMockito.mockStatic(DateUtil.class);
    when(DateUtil.today()).thenReturn("2026-01-08");

    assertEquals("2026-01-08", DateUtil.today());
  }
}

Mock Constructor (new Keyword)

@RunWith(PowerMockRunner.class)
@PrepareForTest({ReportService.class})
public class ReportServiceTest {

  @Test
  public void shouldMockConstructor() throws Exception {
    PdfGenerator mockGen = mock(PdfGenerator.class);

    PowerMockito.whenNew(PdfGenerator.class)
        .withNoArguments()
        .thenReturn(mockGen);

    ReportService service = new ReportService();
    service.generate();

    verify(mockGen).createPdf();
  }
}

Better Modern Alternative: Mockito Static Mocking (No PowerMock)

If you’re on modern Mockito (3.4+), you can mock static methods like this:

try (MockedStatic<DateUtil> mocked = mockStatic(DateUtil.class)) {
  mocked.when(DateUtil::today).thenReturn("2026-01-08");
  assertEquals("2026-01-08", DateUtil.today());
}

✅ Prefer this over PowerMock whenever possible.