ArgumentCaptor in Mockito
Fast recall
Quick revision
Core answer
Interview-ready guide
Interview answer
ArgumentCaptor is a Mockito tool that captures the actual argument passed to a mock so you can inspect it after the method runs.
It's really useful when your code creates an object internally and passes it to a dependency—you can't reference that object directly in your test, but you can capture it and assert on its properties. You declare it with the at-Captor annotation, like at-Captor ArgumentCaptor of Order, which is cleaner than calling ArgumentCaptor dot forClass.
Then in your test, you call verify on your mock and pass captor dot capture where the argument goes—that records what was passed. After verify runs, you call captor dot getValue to get the captured object and assert on its fields.
For example, if OrderService creates a new Order and saves it, you capture that order and check that its amount is correct, its status is PENDING, and so on. One thing to watch out for: you have to call verify before getValue, otherwise you get IllegalStateException because nothing's been captured yet. If the method gets called multiple times, use captor dot getAllValues instead of getValue—it returns a list of all the arguments.
That's how you verify not just that a method was called, but that it received the right data.
ArgumentCaptor in Mockito
Direct Answer
ArgumentCaptor captures the actual argument value passed to a mock so you can perform detailed assertions on it after the method call. Create it with ArgumentCaptor.forClass(ClassName.class) or @Captor annotation, pass captor.capture() in verify, then retrieve the value with captor.getValue() and assert on its properties.
Code Example
@ExtendWith(MockitoExtension.class)
class OrderServiceTest {
@Mock
private OrderRepository orderRepository;
@Captor
private ArgumentCaptor<Order> orderCaptor; // Cleaner than forClass()
@InjectMocks
private OrderService orderService;
@Test
void shouldSaveOrderWithCorrectDetails() {
orderService.placeOrder("Laptop", 1500.00);
verify(orderRepository).save(orderCaptor.capture()); // Capture the saved order
Order capturedOrder = orderCaptor.getValue();
assertThat(capturedOrder.getItem()).isEqualTo("Laptop");
assertThat(capturedOrder.getAmount()).isEqualTo(1500.00);
assertThat(capturedOrder.getStatus()).isEqualTo(OrderStatus.PENDING);
assertThat(capturedOrder.getTimestamp()).isNotNull(); // Verify timestamp was set
}
}
Common Mistakes & Pitfalls
- Calling getValue() before verify(): Freshers often write captor.getValue() before verify(), which throws IllegalStateException because nothing has been captured yet—always verify first, then capture.
- Using captor in when() instead of verify(): Writing when(mock.method(captor.capture())) doesn't make sense because stubbing happens before execution—captors are for verification after execution.
- Forgetting getAllValues() for multiple calls: If the mock is called three times and you use getValue(), you only get the last argument—use getAllValues() to assert all three.
- Not initializing with @Captor: Creating ArgumentCaptor manually without MockitoAnnotations.openMocks(this) or @ExtendWith leads to NullPointerException—always use @Captor or explicitly initialize.
Check your understanding
Answer these without looking back at the article.
- When would you use argThat() instead of ArgumentCaptor?
- Can you use ArgumentCaptor with @Mock annotations without MockitoExtension?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.