Issue
I'm unit testing with mockito and I get nulls in the repository, after doing a .save().
My test:
....
@BeforeEach
void setUp() {
// USUARIO
user = new User();
user.setUserName("Username A");
user.setPassword("Pass A");
user.setConfirmPassword("Pass A");
}
@MockitoSettings(strictness = Strictness.LENIENT)
@Test
void createUserNoExistValidConfirmation() throws Exception {
User userToPassParam = new User();
userToPassParam.setUserName("Username_Aa");
userToPassParam.setPassword("Pass A");
userToPassParam.setConfirmPassword("Pass A");
// checkUserNameAvailable
Mockito.when(userDaoRepository.findByUserName(userToPassParam.getUserName())).thenReturn(Optional.ofNullable(user));
// -- checkPasswordValid
Mockito.when(bCryptPasswordEncoder.encode(userToPassParam.getPassword())).thenReturn(user.getPassword());
// -- save
Mockito.when(userDaoRepository.save(userToPassParam)).thenReturn(user);
User userToCallServiceImpl = new User();
userToCallServiceImpl.setUserName("Username A");
userToCallServiceImpl.setPassword("Pass A");
userToCallServiceImpl.setConfirmPassword("Pass A");
User user = userServiceImpl.createUser(userToCallServiceImpl); // HERE GET NULLS
System.out.println("User: " + user);
System.out.println("this.user: " + this.user);
Assertions.assertEquals(user.getUserName(), this.user.getUserName());
}
.....
value of userToPassParam passed parameter: the expected object
I only treat 3 values of the object, "userName, password, confirmPassword" the other values do not matter to me.
When I try to pass the test: userServiceImpl
@Override
public User createUser(User user) throws Exception {
if (checkUserNameAvailable(user) && checkPasswordValid(user)) {
// cogemos el estado de la DB para más adelante: user = save()
String encodePassword = bCryptPasswordEncoder.encode(user.getPassword());
user.setPassword(encodePassword);
user = userDaoRepository.save(user);
}
return user;
}
The user has a "before save" value. Right when it saves I get a null.
After repository.save(object) the object returned by the .save "mock object" is null.
I don't understand very well why the .save returns null, when in the "when" I specify what to return. It's as if mockito didn't intercept the .save() to return the object.
Note: I use Junit 5, Mockito 4.6.1
I am expecting the .save() to return the "user" as I specified in my @BeforeEach void setUp() {...}. Mockito.when(userDaoRepository.save(userToPassParam)).thenReturn(user); That is, the intercept of the .save() so that it returns the object.
Solution
I have fixed this with an ArgumentMatchers. For some unknown reason, Mockito needs it.
import static org.mockito.ArgumentMatchers.any;
Mockito.when(userDaoRepository.save(any(User.class))).thenReturn(user);
Information source: here
Note: I have also implemented equals and hashCode overrides, but it doesn't detect them.
Answered By - Naslo Flaquez
Answer Checked By - Robin (JavaFixing Admin)