我希望在每个测试用例之后清理数据库而不回滚事务。我尝试过DBUnit的DatabaseOperation.DELETE_ALL,但如果删除违反了外键约束,它就不起作用。我知道我可以禁用外键检查,但这也会禁用对测试的检查(我想阻止)。
我正在使用JUnit 4,JPA 2.0(Eclipselink)和Derby的内存数据库。有什么想法吗?
谢谢, 西奥
答案 0 :(得分:18)
最简单的方法是使用nativeQuery jpa方法。
@After
public void cleanup() {
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
em.createNativeQuery("truncate table person").executeUpdate();
em.createNativeQuery("truncate table preferences").executeUpdate();
em.getTransaction().commit();
}
答案 1 :(得分:4)
简单:在每次测试之前,启动一个新事务,然后在测试之后回滚。这将为您提供与之前相同的数据库。
确保测试不会创建新的交易;而是重用现有的。
答案 2 :(得分:2)
是的,交易中测试会让您的生活更轻松,但如果交易是您的事情,那么您需要在清理期间(@After
)实施补偿交易。这听起来很费劲,但如果得到适当的处理,你最终可能会得到一组辅助方法(在测试中)来补偿(清理)在@Before
和测试期间累积的数据(使用JPA或直接JDBC - 无论什么都有意义)。
例如,如果您在测试期间使用JPA并在实体上调用create方法,则可以使用(如果您喜欢使用AOP或仅使用像我们这样的帮助测试方法),则可以使用所有测试中的模式:
@After
答案 3 :(得分:1)
我有点困惑,因为DBUnit会在每次测试之前将数据库重新初始化为已知状态。
他们recommend as a best practice也不会在测试后清理或以其他方式更改数据。
因此,如果是清理工作,你需要为下一次测试准备数据库,我不会打扰。
答案 4 :(得分:0)
我的设置非常相似:它是Derby(嵌入式)+ OpenJPA 1.2.2 + DBUnit。以下是我处理当前任务的集成测试的方法:在每个@Before
方法中,我运行3个脚本:
我的数据库只有12个表,测试数据集也不是很大 - 约50个记录。每个脚本运行大约需要500毫秒,并且在添加或修改表时手动维护它们。
这种方法可能不建议用于测试大型数据库,也许它甚至不能被视为小型数据库的良好实践;但是,与在@After
方法中回滚事务相比,它有一个重要优势:您可以实际检测提交时发生的情况(如持久化分离实体或乐观锁异常)。
答案 5 :(得分:0)
晚了好,从不...... 我遇到了同样的问题,并提出了一个非常简单的解决方案:
的persistence.xml
<persistence-unit name="Mapping4" transaction-type="RESOURCE_LOCAL" >
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>...</class>
<class>...</class>
<properties>
...
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create" />
...
</properties>
</persistence-unit>
单元测试:
...
@Before
public void setup() {
factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
entityManager = factory.createEntityManager();
}
@After
public void tearDown() {
entityManager.clear();
entityManager.close();
factory.close();
}
...
答案 6 :(得分:0)
每次运行后,我都会删除数据库文件:
boolean deleted = Files.deleteIfExists(Paths.get("pathToDbFile"));
有点脏但是对我有用。 问候
答案 7 :(得分:0)
选项1:您可以在截断表之前禁用外键检查,并在截断后再次启用它们。您仍将以这种方式在测试中进行检查。
选项2::当最后一个连接关闭时,H2数据库将破坏内存数据库。我猜Derby DB支持类似的功能,或者您可以切换到H2。
另请参见:我在以下相关问题中使用Hibernate编写了一段代码,在每次测试之前截断表:https://stackoverflow.com/a/63747005/471214