Careeroza
Mockito Mocks and Stubs
Why Mocks
A service usually depends on other things: a repository (DB), a payment gateway (HTTP), an email sender. A unit test should not hit a real DB or charge a card. A mock is a fake object created by Mockito that returns what you tell it to (stubbing) and records how it was called.
Test ──► OrderService ──► ProductRepository (mock: returns a fixed product)
└──► PaymentGateway (mock: returns SUCCESS / throws)
└──► EmailSender (mock: we only verify it was called)Stubbing with when/thenReturn
@ExtendWith(MockitoExtension.class)
class OrderServiceTest {
@Mock ProductRepository productRepository;
@Mock PaymentGateway paymentGateway;
@Mock EmailSender emailSender;
@InjectMocks OrderService orderService; // real object, mocks injected via constructor
@Test
void placesOrderWhenStockAndPaymentOk() {
// Arrange
Product phone = new Product(1L, "Phone", new BigDecimal("15999"), 5);
when(productRepository.findById(1L)).thenReturn(Optional.of(phone));
when(paymentGateway.charge(any(), eq(new BigDecimal("15999")))).thenReturn(PaymentStatus.SUCCESS);
// Act
Order order = orderService.placeOrder("ravi", 1L, 1);
// Assert
assertEquals(OrderStatus.CONFIRMED, order.status());
assertEquals(4, phone.stock());
}
@Test
void failsWhenProductMissing() {
when(productRepository.findById(99L)).thenReturn(Optional.empty());
assertThrows(ProductNotFoundException.class, () -> orderService.placeOrder("ravi", 99L, 1));
}
@Test
void paymentGatewayDown() {
when(productRepository.findById(1L)).thenReturn(Optional.of(new Product(1L, "Phone", BigDecimal.TEN, 5)));
when(paymentGateway.charge(any(), any())).thenThrow(new GatewayTimeoutException("Razorpay timeout"));
Order order = orderService.placeOrder("ravi", 1L, 1);
assertEquals(OrderStatus.PAYMENT_PENDING, order.status());
}
}Stubbing Cheat Sheet
| Code | Effect |
|---|---|
when(m.call()).thenReturn(x) | return x |
thenReturn(a, b, c) | a on 1st call, b on 2nd, c afterwards |
thenThrow(ex) | throw |
thenAnswer(inv -> ...) | compute the answer from the arguments |
doThrow(ex).when(m).voidMethod() | stub void methods |
any(), eq(x), anyString(), argThat(pred) | argument matchers (if one argument uses a matcher, all must) |
Note: Mockito (with MockitoExtension) uses strict stubs: an unused when(...) fails the test with UnnecessaryStubbingException, which keeps tests clean.