What is Mockito's `ArgumentCaptor`, and how is it different from matchers?

Can anyone provide a clear example demonstrating how to use org.mockito.ArgumentCaptor in Mockito? I have read the official documentation, but it doesn’t explain it with enough clarity. Additionally, how does ArgumentCaptor differ from the built-in matchers provided by Mockito?

Using ArgumentCaptor If you need to capture and assert the exact value passed to a method call, ArgumentCaptor is the way to go. It’s perfect when you want to check the exact argument passed to a mocked method.

Example:

ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
verify(mockService).doSomething(captor.capture());
assertEquals("John", captor.getValue());

This captures the String passed to doSomething and allows you to assert that it’s the exact value you expect.

If you don’t care about the exact argument but want to match arguments with a certain type or value condition, matchers are a good option. You can use matchers like any(), eq(), or anyString() to match parameters loosely.

verify(mockService).doSomething(anyString()); This verifies that doSomething was called with any String as the argument.

You can use both ArgumentCaptor and matchers together in situations where you want to verify a method call using matchers but also need to capture and verify the argument value at a later stage.

Example:

ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
when(mockService.doSomething(anyString())).thenReturn(null);
mockService.doSomething("John");
verify(mockService).doSomething(captor.capture());
assertEquals("John", captor.getValue());

This lets you stub the method using matchers for flexibility but still captures the argument passed and verifies it precisely later.