基于 JPA 的 JUnit 测试最佳实践

2022-09-01 11:03:04

这是一个有点奇怪的问题,但它已经困扰了我几个月了。我已经使用Wicket + Hibernate(使用Maven构建)构建了一个基于JPA的Web应用程序,并希望直接测试DAO层。我创建了一个特定的src/test/resources/META-INF/persistence.xml文件,用于测试,但与WTP等一直发生冲突。为了解决这些问题,我创建了一个单独的测试项目,单元测试位于其中。有没有更好的方法来管理JPA项目的单元测试,而无需在持久性文件之间进行决斗?

附录:其他测试框架(例如TestNG)会让这变得更容易吗?


答案 1

你可能想试试嘲笑。测试的工作方式如下:

你用嘲笑来“实现” 。而不是真正的代码,你使用 mockito 的方法说“如果应用程序调用 ,则返回此对象”。在后台,mockito 将创建一个代理实例,该代理实例拦截 Java 方法调用并返回您指定的值。对其他方法的调用将返回 。EntityManagergetReference()null

像这样的东西以相同的方式工作,但你首先需要创建一个模型,然后使用与 中相同的方法(返回查询模型)。createQuery()QuerygetReference()

由于您不使用真正的EM,因此不需要真正的.persistence.xml

一个更简单的解决方案是,如果您可以设置一些属性来更改文件的名称,但我认为这是不可能的。persistence.xml

其他一些可能有帮助的链接:


答案 2

我们使用双重持久性.xml文件用于生产和测试运行时,但这只是一个与类路径相关的问题(我们使用Eclipse,但不严重依赖WTP插件)。两者之间的唯一区别是生产版本不包含实体定义。

我们不使用模拟框架来测试JPA,因为这不会为我们的测试增加任何价值。这些测试确实使用JPA运行真实的数据访问,JPA与PostgreSQL数据库通信。

我们的测试方法基于持久性层的Spring测试框架:事务内测试。我们的应用程序是基于Spring的,但这种方法同样适用于想要利用Spring测试类的任意应用程序。本质是每个测试都在一个从不提交的事务中运行,并且在最后(在拆解中)它会自动回滚。这以非常好的不显眼和透明的方式解决了数据污染和测试依赖性的问题。

Spring测试框架是灵活的,允许多事务测试,但这些是特殊情况,不超过测试的10%。

我们仍然使用对JUnit 3.8的旧版支持,但新的JUnit 4的Spring TestContext框架看起来非常有吸引力。

为了设置事务内测试数据,我们使用构建业务实体的内部实用程序类。由于它是在所有测试之间共享的,因此维护和支持的开销大大超过了具有标准和可靠方法来设置测试数据的好处。

Spring DI有助于使测试简洁和自我描述,但它不是一个关键功能。


推荐