java - 实体层的 SpringBoot、JPA 和 Hibernate 单元测试
问题描述
我正在使用 SpringBoot、JPA 和 Hibernate 实现一个项目。
我使用 JPA 存储库实现了 DB 实体层。
我有兴趣了解为这一层编写单元测试的最佳实践。
- 第一点:对于这一层,从您的角度来看,有必要使用集成数据库还是使用 Mockito 进行模拟?
- 我的想法,对于这一层,例如,测试实体结构:例如检查字段验证,插入和检索一些数据。通过这种方式,我想我可以涵盖整个数据层的测试。
我试图了解这些最佳实践,同时,我尝试编写测试的第一个示例:
@ActiveProfiles("test")
@DisplayName("Test Item JPA Entity")
@DataJpaTest
@AutoConfigureTestDatabase( replace = AutoConfigureTestDatabase.Replace.NONE )
public class ItemEntityTest {
@Autowired
MyEntityRepository repo;
@Test
@Transactional
public void testEntityCreation() {
Entity e = new Entity();
e.setMyField1("A");
e.setMyField1("A");
//e.setMandatoryField("C")
repo.save(e);
}
}
不幸的是,在这种情况下,我注意到没有应用字段验证(@NotNull 或@NotEmpty,或@Column(nullable = false)等......如果我尝试将实体保存到我的应用程序中,验证工作正常。 .. 引发异常)。为什么?
还有一些“自动字段”(例如创建时间和最后修改时间)没有填写。
这是正确的路径吗?何来测试我的实体定义?
解决方案
正如那个答案中提到的,问题在于@DataJpaTest
spring将使用TestEntityManager
并且事务注释将覆盖spring boot的默认自动提交和回滚行为。
因此,您的测试方法将通过并假设 hibernate 是此处使用的 ORM,当最终进行刷新时,将触发 hibernate 的 pre-insert 事件并应用验证,但您的测试用例将在此之前通过,因此它将产生误报(如 spring 文档中使用的术语)
解决方案:您需要在测试中注入实体管理器并手动刷新它,以便在测试完成之前触发休眠预插入事件。
@ActiveProfiles("test")
@DisplayName("Test Item JPA Entity")
@DataJpaTest
@AutoConfigureTestDatabase( replace = AutoConfigureTestDatabase.Replace.NONE )
public class ItemEntityTest {
@Autowired
MyEntityRepository repo;
@Autowired
private TestEntityManager em;
@Test
@Transactional
public void testEntityCreation() {
Entity e = new Entity();
e.setMyField1("A");
e.setMyField1("A");
//e.setMandatoryField("C")
repo.save(e);
em.flush();
}
}
这必须触发您对所应用实体的验证,这在spring framework docs中有记录。 请注意,文档是关于 spring 框架并使用会话工厂,但概念是相同的
您也可以查看spring boot docs,它指向 spring 框架文档以了解此行为。
推荐阅读
- python-3.x - 我正在尝试打开一个文件,查找“r”或“R”作为每个单词的第一个字母,然后打印这些单词
- php - PHP MySQL 使用 INSERT SELECT 后将插入的值设置为 PHP 变量
- python - AttributeError:模块“opensim”没有属性“模型”
- maven - 在apache maven中,如何强制添加省略的依赖jar?
- python - python数据框根据单元格选择行,单元格是列表中的列表
- php - Laravel 5:可更新列表|表格
- javascript - JavaScript 循环遍历 JSON 数据并在 html 中打印
- powershell - Windows.Networking.NetworkOperators 中的 TetheringWiFiBand
- c# - 如何显示完整应用程序的会话超时警告弹出窗口
- sql - 对齐偏移数据值sql join