集成测试
Hibernate 有数千个集成测试,每个单元测试都是独立运行的。传统上,每个测试都需要打开一个 EntityManager
,并通过调用 begin、commit 和 rollback 来协调底层数据库事务。
EntityManager entityManager = getOrCreateEntityManager();
entityManager.getTransaction().begin();
try {
entityManager.persist( item );
assertTrue( entityManager.contains( item ) );
entityManager.getTransaction().commit();
}
catch (Exception e){
if ( entityManager.getTransaction() != null &&
entityManager.getTransaction().isActive() ) {
entityManager.getTransaction().rollback();
}
throw e;
}
finally {
entityManager.close();
}
这非常冗长,因为我们需要确保 EntityManager
总是会被关闭,以便将连接释放回池中。更重要的是,数据库事务必须在每次失败时回滚,否则可能会保留锁,从而阻止模式删除过程。
因此,我们决定将整个 EntityManager
和 JPA 事务管理逻辑提取到一个公共工具类中
import static org.hibernate.testing.transaction.TransactionUtil.*;
这些实用工具的伟大之处在于,您甚至不需要创建它们。我们已经为您做好了准备!
您只需将以下依赖项添加到您的 Maven pom.xml
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-testing</artifactId>
<version>5.2.2.Final</version>
</dependency>
因此,之前的测试用例简化为四行代码
doInJPA( this::entityManagerFactory, entityManager -> {
entityManager.persist( item );
assertTrue( entityManager.contains( item ) );
} );
太棒了!
上述示例依赖于存在返回 EntityManagerFactory
实例的 entityManagerFactory()
方法。
如果您更喜欢 Hibernate 本地 API,可以这样做
doInHibernate( this::sessionFactory, session -> {
session.persist( item );
assertTrue( session.contains( item ) );
} );
类似于前面的示例,假设测试类中存在一个返回 SessionFactory
的 sessionFactory()
方法。然而,您可以按任何您喜欢的名称命名这些方法,只需确保更新 doInJPA
或 doInHibernate
方法的第一个参数即可。
幕后
如果您对底层实现感兴趣,请查看 GitHub 上的 源代码。
享受测试吧!