spring-bootunit-testingliterals

mockito test data from val to literals springboot


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


Solution

  • 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.