【发布时间】:2017-11-10 21:34:10
【问题描述】:
我正在使用 SpringBoot/Kotlin/JPA/Hibernate/Junit 并有 JpaServiceTest 类来练习与单个实体相关的存储库方法。 JpaService 类的方法名遵循findByXXXXId、findAll、updateXXXX、addXXXX 和deleteXXXX 的约定。
为了保持一致性,我使用相同的约定命名 JpaTest 类中的方法。我的 JpaTest 类有两个 findById 场景,一个是“空”,另一个是返回映射实体。我的应用程序按预期工作,但是我的测试类在预期返回有效实体的 findById 场景中失败。
The service class
@Service("MyService")
@Transactional
internal class JpaMyService(val MyRepo: MyRepository) : MyService {
val log = LoggerFactory.getLogger("MyService")
override fun findByMyId(MyId: Long): MyDto? {
log.debug("Retrieving My: {}", MyId)
return MyRepo.findOne(MyId)?.toDto()
}
override fun findAllMys(): List<MyDto> {
log.debug("Retrieving Mys")
return MyRepo.findAll().map { it.toDto() }
}
override fun updateMy(id: Long?, My: UpdateMyDto): MyDto? {
log.debug("Updating My: {} with data: {}", id, My)
val currentMy = MyRepo.findOne(id)
return if (currentMy != null) MyRepo.save(MyEntity.fromDto(My, currentMy)).toDto()
else null
}
override fun addMy(My: CreateMyDto): MyDto {
log.debug("Adding My: {}", My)
return MyRepo.save(MyEntity.fromDto(My)).toDto()
}
override fun deleteMy(id: Long?) {
log.debug("Deleting My: {}", id)
MyRepo.delete(id)
}
冒犯的方法
@Test
fun `'findMyById' should map existing entity from repository`() {
repository.save(MyEntity(1, "name", "description"))
val result = service.findByMyId(1)
softly.assertThat(result?.id).isEqualTo(1)
softly.assertThat(result?.name).isEqualTo("name")
softly.assertThat(result?.description).isEqualTo("description")
}
Test failure
org.junit.ComparisonFailure:
Expected :"name"
Actual :null
将失败的 findByMyId 方法的名称更改为 getByMyId 或 retrieveByMyId 允许测试用例从命令行和 IDE 成功通过。无论名称如何,如果作为单个测试运行,该测试将始终从 IDE 运行,但是当测试类作为一个整体运行时,它将失败。
我想知道使用 findByXXId 返回和 Entity 的问题是什么,当我将测试方法的名称更改为以 get 或 retrieve 开头时,这有效。如果我使用任何其他方法名称,它也会失败,更重要的是,即使我在其他服务和测试类中更改方法名称,我也会看到失败,因为 NPE。
如果这没有意义,请提前道歉,但我是这个堆栈的新手,并且在应用程序运行良好的情况下,我花了三天时间来确定为什么这些测试会失败。
【问题讨论】:
-
听起来您的测试依赖于其他测试,并且名称更改会影响测试的顺序。尝试在 repository.save 之后添加一个 repository.flush 并使用 @Transactional 注释测试
-
我尝试了这两个建议,但问题仍然存在。如果我将测试方法命名为 findByXXXXId,它会失败,但如果我保持实现完全相同,但将其重命名为 getByXXXXId 或 retrieveByXXXXId,则在执行整个测试类时测试成功通过。
标签: java hibernate junit spring-data-jpa junit5