DataJPATest Junit方法命名和NullPointerExceptions

我正在使用SpringBoot / Kotlin / JPA / Hibernate / Junit,并且拥有JpaServiceTest类,可以执行与单个实体有关的存储库方法。 JpaService类的方法名遵循约定findByXXXXIdfindAlladdXXXXaddXXXXdeleteXXXX

为了保持一致性,我使用相同的约定为JpaTest类中的方法命名。 我的JpaTest类有两个findById场景,其中’Null’预期是另一个返回映射实体的地方。 我的应用程序按预期方式工作,但是我的测试类在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 { 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方法的名称更改为getByMyIdretrieveByMyId可以使测试用例从命令行和IDE中成功传递。 如果作为单个测试运行,测试将始终从IDE运行,而不考虑名称,但是当测试类作为整体运行时,将会失败。

我想知道什么问题是使用findByXXId返回和实体,这个工程时,我改变了测试方法的名称开始与获取或检索。 如果我使用任何其他方法名称,它也会失败,甚至当我在其他服务和测试类中更改方法名称时,由于NPE,我看到失败。

如果没有任何意义,我会事先抱歉,但是我对这个堆栈很陌生,需要三天的时间来确定为什么这些测试在应用程序运行的非常好时失败了。

由于我在评论中的第一个建议似乎没有解决这个问题,所以这里列出了一些事情要做,以隔离问题。

首先,为了确保我已经掌握了事实:

  • 您的测试在IDE中工作
  • 运行所有其他测试时(假设使用Maven或类似的),测试失败
  • 与所有其他测试一起运行时,您的测试将起作用,但会重命名。

我的意见仍然认为:这不是直接关系到名字,而是测试之间的相互依赖关系。

  1. 创建一个在IDE中重现问题的最小方案。

    a)在IDE中运行所有的测试(应该可以通过选择测试源文件夹并选择“运行测试”或其他)。

    b)假设测试失败通过选择树的越来越小的部分来缩小测试范围。

    c)如果IDE中的测试完全没有失败,那么可以使用Maven中的include / exclude或者其他可以使用的构建工具来做同样的事情。

    d)另一个变化是创建包含所有测试的专用TestSuite。

    一般来说,通过在每一步中删除大约一半的测试,你应该能够在合理的时间内完成两个测试的测试套件:有问题的测试和另外一个测试触发第一个测试失败。

  2. 激活SQL和事务处理的日志记录。

    在第一次测试之后,您应该看到回滚。 接着是第二个测试的插入。 你不应该看到任何提交。

    如果你没有看到回滚,你的测试或者没有用@Transactional注释,或者出于某种原因没有收到交易。

    如果您没有看到插入,您的更改似乎不会被刷新。

  3. 使用JDBC模板发出select语句来查看数据库的内容。 使用简单的语句,如select * from x 。 没有where子句,没有连接。 记录结果。

有了这些信息,问题就变得很明显了。 如果不更新这个问题和评论这个答案。 我会再看一次。