Test Overview
This test verifies that a method correctly calls a dependency with the expected argument by capturing the argument passed to a mocked method using an argument captor.
This test verifies that a method correctly calls a dependency with the expected argument by capturing the argument passed to a mocked method using an argument captor.
import static org.mockito.Mockito.*; import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; class UserServiceTest { interface UserRepository { void saveUser(String username); } static class UserService { private final UserRepository repo; UserService(UserRepository repo) { this.repo = repo; } void registerUser(String username) { // Some logic before saving repo.saveUser(username); } } @Test void testRegisterUserCapturesArgument() { UserRepository mockRepo = mock(UserRepository.class); UserService service = new UserService(mockRepo); service.registerUser("alice"); ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class); verify(mockRepo).saveUser(captor.capture()); String capturedArg = captor.getValue(); assertEquals("alice", capturedArg); } }
| Step | Action | System State | Assertion | Result |
|---|---|---|---|---|
| 1 | Test starts | JUnit test runner initializes the test class UserServiceTest | — | PASS |
| 2 | Creates a mock UserRepository using Mockito | mockRepo is a mock object that records interactions | — | PASS |
| 3 | Creates UserService instance with mockRepo injected | UserService instance ready to use mockRepo | — | PASS |
| 4 | Calls registerUser("alice") on UserService | Inside registerUser, calls mockRepo.saveUser("alice") | — | PASS |
| 5 | Creates ArgumentCaptor for String class | ArgumentCaptor ready to capture String arguments | — | PASS |
| 6 | Verifies mockRepo.saveUser was called and captures the argument | Captured argument is stored inside captor | Verify that saveUser was called once with any String argument | PASS |
| 7 | Retrieves captured argument and asserts it equals "alice" | Captured argument is "alice" | assertEquals("alice", capturedArg) | PASS |
| 8 | Test ends successfully | Test passed with all assertions met | — | PASS |
ArgumentCaptor in JUnit tests with Mockito?ArgumentCaptor for a String argument in JUnit with Mockito?forClass() with the class type.ArgumentCaptor.forClass(String.class), which is correct. Options B and C incorrectly use constructors, which are not public. ArgumentCaptor<String> captor = ArgumentCaptor.capture(String.class); uses a non-existent method capture() for creation.List<String> list = mock(List.class);
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
list.add("hello");
verify(list).add(captor.capture());
String captured = captor.getValue();add("hello") called, so "hello" is passed as argument.verify(list).add(captor.capture()) captures the argument passed to add(), which is "hello".ArgumentCaptor<Integer> captor = ArgumentCaptor.forClass(Integer.class); verify(mockedList).add(captor.capture()); mockedList.add(5); Integer value = captor.getValue();
verify() call must come after the actual method call to check interactions.verify() is called before mockedList.add(5), so no interaction is recorded yet.verify call is before the actual method call -> Option DgetAllValues().getAllValues() after verifying two calls correctly uses one captor and retrieves all captured arguments. Create two separate ArgumentCaptors and verify each call separately is unnecessary and verbose. Use ArgumentCaptor only once; it cannot capture multiple calls is false; captor supports multiple captures. Capture arguments by stubbing the method instead of verify is incorrect because stubbing does not capture arguments.getAllValues() after verifying two calls -> Option CPass the test and this pattern moves unknown