Argument captors in JUnit - Build an Automation Script
import static org.mockito.Mockito.*; import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) class UserServiceTest { @Mock UserRepository userRepository; @InjectMocks UserService userService; @Test void testCreateUser_callsRepositoryWithCorrectUser() { // Arrange User expectedUser = new User("Alice", "alice@example.com"); // Act userService.createUser("Alice", "alice@example.com"); // Assert ArgumentCaptor<User> userCaptor = ArgumentCaptor.forClass(User.class); verify(userRepository, times(1)).save(userCaptor.capture()); User capturedUser = userCaptor.getValue(); assertEquals(expectedUser.getName(), capturedUser.getName()); assertEquals(expectedUser.getEmail(), capturedUser.getEmail()); } } // Supporting classes class User { private String name; private String email; public User(String name, String email) { this.name = name; this.email = email; } public String getName() { return name; } public String getEmail() { return email; } } interface UserRepository { void save(User user); } class UserService { private final UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository = userRepository; } public void createUser(String name, String email) { User user = new User(name, email); userRepository.save(user); } }
This test uses Mockito with JUnit 5 to verify that the UserService calls the save method of UserRepository with the correct User object.
We use @ExtendWith(MockitoExtension.class) to enable Mockito annotations.
The @Mock annotation creates a mock UserRepository. The @InjectMocks annotation creates a UserService instance and injects the mock repository.
In the test method, we call createUser on the service. Then we use ArgumentCaptor to capture the User object passed to save.
We verify that save was called exactly once. Then we assert that the captured User has the expected name and email.
This approach helps us check the exact argument passed to a mocked method, which is useful when the argument is created inside the method under test.
Now add data-driven testing with 3 different user inputs to verify the repository is called correctly each time