I have a Spring Boot application and an UPDATE method for user entity:
<code>@Transactional
public void updateUser(@Min(1) Long userId,
@Email String email,
@NotBlank @Length(min = 8, max = 20) String password,
@NotBlank @Length(max = 30) String username) throws UpdateUserException {
UserEntity user = userRepository.findById(userId).orElseThrow(
() -> new UpdateUserException("User with ID " + userId + " does not exist")
);
if (isUserExists(email, username)) {
throw new UpdateUserException("User with email " + email +
" or username " + username + " already exists");
}
user.setEmail(email);
user.setPassword(password);
user.setUsername(username);
}
private boolean isUserExists(String email, String username) {
return userRepository.findByEmail(email).isPresent() ||
userRepository.findByUsername(username).isPresent();
}
</code>
<code>@Transactional
public void updateUser(@Min(1) Long userId,
@Email String email,
@NotBlank @Length(min = 8, max = 20) String password,
@NotBlank @Length(max = 30) String username) throws UpdateUserException {
UserEntity user = userRepository.findById(userId).orElseThrow(
() -> new UpdateUserException("User with ID " + userId + " does not exist")
);
if (isUserExists(email, username)) {
throw new UpdateUserException("User with email " + email +
" or username " + username + " already exists");
}
user.setEmail(email);
user.setPassword(password);
user.setUsername(username);
}
private boolean isUserExists(String email, String username) {
return userRepository.findByEmail(email).isPresent() ||
userRepository.findByUsername(username).isPresent();
}
</code>
@Transactional
public void updateUser(@Min(1) Long userId,
@Email String email,
@NotBlank @Length(min = 8, max = 20) String password,
@NotBlank @Length(max = 30) String username) throws UpdateUserException {
UserEntity user = userRepository.findById(userId).orElseThrow(
() -> new UpdateUserException("User with ID " + userId + " does not exist")
);
if (isUserExists(email, username)) {
throw new UpdateUserException("User with email " + email +
" or username " + username + " already exists");
}
user.setEmail(email);
user.setPassword(password);
user.setUsername(username);
}
private boolean isUserExists(String email, String username) {
return userRepository.findByEmail(email).isPresent() ||
userRepository.findByUsername(username).isPresent();
}
Now I want to write a Unit test for it.
I tried to write such test, but it does not work because Spring automatically updates user in DB without invoking userRepository.save().
<code>@Test
void canUpdateUser() throws UpdateUserException {
Long id = 1L;
String newEmail = "[email protected]";
String newPassword = "12345678";
String newUsername = "NewUsername";
// given
UserEntity user = new UserEntity(
id,
"[email protected]",
"00000000",
"OldUsername"
);
given(userRepository.findById(anyLong())).willReturn(Optional.of(user));
// when
underTest.updateUser(id, newEmail, newPassword, newUsername);
// then
ArgumentCaptor<UserEntity> userEntityArgumentCaptor=ArgumentCaptor.forClass(UserEntity.class);
verify(userRepository).save(userEntityArgumentCaptor.capture());
UserEntity capturedUser = userEntityArgumentCaptor.getValue();
assertThat(capturedUser.getId()).isEqualTo(id);
assertThat(capturedUser.getEmail()).isEqualTo(newEmail);
assertThat(capturedUser.getPassword()).isEqualTo(newPassword);
assertThat(capturedUser.getUsername()).isEqualTo(newUsername);
}
</code>
<code>@Test
void canUpdateUser() throws UpdateUserException {
Long id = 1L;
String newEmail = "[email protected]";
String newPassword = "12345678";
String newUsername = "NewUsername";
// given
UserEntity user = new UserEntity(
id,
"[email protected]",
"00000000",
"OldUsername"
);
given(userRepository.findById(anyLong())).willReturn(Optional.of(user));
// when
underTest.updateUser(id, newEmail, newPassword, newUsername);
// then
ArgumentCaptor<UserEntity> userEntityArgumentCaptor=ArgumentCaptor.forClass(UserEntity.class);
verify(userRepository).save(userEntityArgumentCaptor.capture());
UserEntity capturedUser = userEntityArgumentCaptor.getValue();
assertThat(capturedUser.getId()).isEqualTo(id);
assertThat(capturedUser.getEmail()).isEqualTo(newEmail);
assertThat(capturedUser.getPassword()).isEqualTo(newPassword);
assertThat(capturedUser.getUsername()).isEqualTo(newUsername);
}
</code>
@Test
void canUpdateUser() throws UpdateUserException {
Long id = 1L;
String newEmail = "[email protected]";
String newPassword = "12345678";
String newUsername = "NewUsername";
// given
UserEntity user = new UserEntity(
id,
"[email protected]",
"00000000",
"OldUsername"
);
given(userRepository.findById(anyLong())).willReturn(Optional.of(user));
// when
underTest.updateUser(id, newEmail, newPassword, newUsername);
// then
ArgumentCaptor<UserEntity> userEntityArgumentCaptor=ArgumentCaptor.forClass(UserEntity.class);
verify(userRepository).save(userEntityArgumentCaptor.capture());
UserEntity capturedUser = userEntityArgumentCaptor.getValue();
assertThat(capturedUser.getId()).isEqualTo(id);
assertThat(capturedUser.getEmail()).isEqualTo(newEmail);
assertThat(capturedUser.getPassword()).isEqualTo(newPassword);
assertThat(capturedUser.getUsername()).isEqualTo(newUsername);
}