i made a unit test, it works fine. Now i got a task to change the data from variables in the test body to literals, to make it more readable. So i did and got problem:
this test passes successfully:
@Test
fun createUser_Success() {
val teamEntity = TeamEntity(1, "testRu", "testEn", "testKk")
val teamSet = mutableSetOf(teamEntity)
val userEntity = UserEntity(1, "test", Role.OWNER, teamSet)
val userRequestDto = UserRequestDto("test", Role.OWNER, listOf(1))
val userResponseDto = UserResponseDto(1, "test", Role.OWNER, teamSet)
doNothing().whenever(teamService).teamExistenceCheck(userRequestDto)
whenever(teamService.teamIdsToTeamSet(userRequestDto)).thenReturn(teamSet)
whenever(userMapper.toEntity(userRequestDto, teamSet)).thenReturn(userEntity)
whenever(userRepository.save(userEntity)).thenReturn(userEntity)
whenever(userMapper.toDto(userEntity)).thenReturn(userResponseDto)
val result = userService.createUser(userRequestDto)
assertEquals(userResponseDto, result)
verify(userRepository).save(userEntityCaptor.capture())
val capturedEntity = userEntityCaptor.value
assertNotNull(capturedEntity)
assertEquals(userEntity, capturedEntity)
verify(teamService).teamExistenceCheck(userRequestDto)
verify(teamService).teamIdsToTeamSet(userRequestDto)
verify(userMapper).toEntity(userRequestDto, teamSet)
verify(userRepository).save(userEntity)
verify(userMapper).toDto(userEntity)
}
this test fails, when i change userRequestDto
to UserRequestDto("test", Role.OWNER, listOf(1))
in test body
@Test
fun createUser_Success() {
val teamEntity = TeamEntity(1, "testRu", "testEn", "testKk")
val teamSet = mutableSetOf(teamEntity)
val userEntity = UserEntity(1, "test", Role.OWNER, teamSet)
val userRequestDto = UserRequestDto("test", Role.OWNER, listOf(1))
val userResponseDto = UserResponseDto(1, "test", Role.OWNER, teamSet)
doNothing().whenever(teamService).teamExistenceCheck(UserRequestDto("test", Role.OWNER, listOf(1)))
whenever(teamService.teamIdsToTeamSet(UserRequestDto("test", Role.OWNER, listOf(1)))).thenReturn(teamSet)
whenever(userMapper.toEntity(userRequestDto, teamSet)).thenReturn(userEntity)
whenever(userRepository.save(userEntity)).thenReturn(userEntity)
whenever(userMapper.toDto(userEntity)).thenReturn(userResponseDto)
val result = userService.createUser(userRequestDto)
assertEquals(userResponseDto, result)
verify(userRepository).save(userEntityCaptor.capture())
val capturedEntity = userEntityCaptor.value
assertNotNull(capturedEntity)
assertEquals(userEntity, capturedEntity)
verify(teamService).teamExistenceCheck(userRequestDto)
verify(teamService).teamIdsToTeamSet(userRequestDto)
verify(userMapper).toEntity(userRequestDto, teamSet)
verify(userRepository).save(userEntity)
verify(userMapper).toDto(userEntity)
}
What is the problem in that fail?
What is the common practice in writing tests? Is it a good idea to insert literals instead of using variables in tests? In my opinion the code looks worse (longer) in that case
It fails because they are different objects,ie
userRequestDto = UserRequestDto("test", Role.OWNER, listOf(1))
is not the same object as
UserRequestDto("test", Role.OWNER, listOf(1))
In spite of them being constructed from with the same argument values. The default behaviour of equals()
is simply to check that they are the same object reference.
The solution is to override the equals()
method by defining it in UserRequestDto
Not sure what this has to do with literals though.