Issue
i Have following UserServiceImpl Service Class:
@Service @Transactional
public class UserServiceImpl implements UserDetailsService {
...
public void addRoleToUser(String username, String name) {
User user = this.userRepository.findByUsername(username);
Role role = this.roleRepository.findByName(name);
user.getRoles().add(role);
}
}
and it's corresponding test class:
public class UserServiceImplTest {
@Mock private UserRepository userRepository;
@Mock private RoleRepository roleRepository;
private AutoCloseable autoCloseable;
private UserServiceImpl userServiceImpl;
@BeforeEach
void setUp(){
autoCloseable = MockitoAnnotations.openMocks(this);
userServiceImpl = new UserServiceImpl(userRepository, roleRepository);
}
@AfterEach
void tearDown() throws Exception{
autoCloseable.close();
}
@Test
void testAddRoleToUser() {
... // user and role def. here
userServiceImpl.addRoleToUser(username, roleName);
// what should be here?
}
}
But how can I verify that user.getRoles().add(role);
is invoked in unit test? Is using mockito, and ArgumentCaptor enough?
Thank you.
Solution
Since userRepository
is a mock, you probably define a behaviour for the findByUsername
call and return an object there. The object is created in the test method (in the "given" block), so you have access to it after calling the method (in the "then" block). You can simply verify if the object contains a given role like so (AssertJ ussage assumed):
assertThat(user.getRoles())
.contains(role);
roleRepository
is also a mock, so the role
object is probably also available in the test. If it was not the case, information about the role could be extracted from the asserted object(s) and verified (for example a name as a String).
Answered By - Jonasz
Answer Checked By - Marilyn (JavaFixing Volunteer)