I try to do unit tests in simple CRUD app on Spring boot + Kotlin.
I already did the tests for other entities and repos but have problems with User entity and repo.
That table is linked to table Team, probably that is why standart logic of my tests does not work.
Springboot version “3.2.4”
Entity
@Entity
@Table(name = ""user"")
@DynamicUpdate
class UserEntity(
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_generator")
@SequenceGenerator(name = "user_generator", sequenceName = "user_id_seq", allocationSize = 1)
@Column(name = "id")
var userId: Int?,
@Column(name = "email")
val email: String,
@Enumerated(EnumType.STRING)
@Column(name = "role", columnDefinition = "user_role_enum", nullable = false)
val role: Role,
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(
name = "user_teams_team",
joinColumns = [JoinColumn(name = "user_id")],
inverseJoinColumns = [JoinColumn(name = "team_id")]
)
val teams: Set<TeamEntity>? = null
)
@Entity
@Table(name = "team")
@DynamicUpdate
class TeamEntity(
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "team_generator")
@SequenceGenerator(name = "team_generator", sequenceName = "team_id_seq", allocationSize = 1)
@Column(name = "id")
var teamId: Int?,
@Column(name = "name_ru")
val nameRu: String,
@Column(name = "name_en")
val nameEn: String,
@Column(name = "name_kk")
val nameKk: String
)
DTO
class UserDto(
val email: String,
val role: Role,
val teams: List<Int>?
)
data class UserResponseDto(
val userId: Int,
val email: String,
val role: Role,
var teams: Set<TeamEntity>?
)
UserServiceImpl
override fun createUser(userDto: UserDto): UserResponseDto {
checkIfSuchTeamsExistOrThrowNotFoundException(userDto)
val teamSet = teamServiceImpl.createTeamSetFromTeamIdsOrThrowNotFoundException(userDto)
val savedUser = userRepository.save(userMapper.toEntity(userDto, teamSet))
return userMapper.toDto(savedUser)
}
private fun checkIfSuchTeamsExistOrThrowNotFoundException(userDto: UserDto) {
val existingInDbTeamIdList = teamRepository.findAll().map { it.teamId!! }
userDto.teams?.forEach { teamId ->
if (teamId !in existingInDbTeamIdList) {
throw NotFoundException("There is no team with id: $teamId")
}
}
}
TeamServiceImpl
fun createTeamSetFromTeamIdsOrThrowNotFoundException(userDto: UserDto): MutableSet<TeamEntity> {
val teamSet: MutableSet<TeamEntity> = mutableSetOf()
userDto.teams?.forEach { teamId ->
val teamEntity = teamRepository.findById(teamId)
.orElseThrow { NotFoundException("There is no team with id: $teamId") }
teamSet.add(teamEntity)
}
return teamSet
}
UserServiceImplTests
@ExtendWith(SpringExtension::class)
@TestInstance(TestInstance.Lifecycle.PER_METHOD)
class UserServiceImplTests {
@Mock
private lateinit var teamMapper: TeamMapper
@Mock
private lateinit var userRepository: UserRepository
@Mock
private lateinit var teamRepository: TeamRepository
@Mock
private lateinit var teamService: TeamServiceImpl
@Mock
private lateinit var userMapper: UserMapper
@InjectMocks
private lateinit var userService: UserServiceImpl
@Captor
private lateinit var userEntityCaptor: ArgumentCaptor<UserEntity>
@Test
fun createUser_Success() {
val id = 1
val teamEntity = TeamEntity(id, "testRu", "testEn", "testKk")
val userEntity = UserEntity(id, "test", Role.OWNER, setOf(teamEntity))
val userEntity1 = UserEntity(id, "test", Role.OWNER, setOf(teamEntity))
val teamSet = mutableSetOf(teamEntity)
val userDto = UserDto("test", Role.OWNER, listOf(1))
val userResponseDto = UserResponseDto(id, "test", Role.OWNER, setOf(teamEntity))
whenever(teamRepository.findAll()).thenReturn(listOf(teamEntity))
whenever(teamRepository.findById(id)).thenReturn(Optional.of(teamEntity))
whenever(userMapper.toEntity(userDto, teamSet)).thenReturn(userEntity)
whenever(userRepository.save(userEntity)).thenReturn(userEntity)
whenever(userMapper.toDto(userEntity)).thenReturn(userResponseDto)
val result = userService.createUser(userDto)
assertEquals(userResponseDto, result)
verify(userRepository).save(userEntityCaptor.capture())
val capturedEntity = userEntityCaptor.value
assertNotNull(capturedEntity)
assertEquals(userEntity, capturedEntity)
verify(userRepository).save(userEntity)
verify(teamRepository).findAll()
}
THis is the error itself:
save(...) must not be null
java.lang.NullPointerException: save(...) must not be null
at kt.cell.jobsapi.service.impl.UserServiceImpl.createUser(UserServiceImpl.kt:39)
at kt.cell.jobsapi.service.impl.UserServiceImplTests.createUser_Success(UserServiceImplTests.kt:123)
I just dont understand where to look for