Micronaut 和 JUnit 回滚
Posted
技术标签:
【中文标题】Micronaut 和 JUnit 回滚【英文标题】:Micronaut and JUnit rollback 【发布时间】:2020-04-27 00:01:58 【问题描述】:我为 micronaut 微服务编写了一些测试。我希望在我的测试完成后,数据库中的所有更改都被还原(回滚)。首先,我写了一个似乎可行的简单示例。更改被还原。但是当我使用相同的类比运行微服务测试时,更改不会恢复。
简单的工作示例:
@Test
@Transactional
public void testRollback()
try (Connection connection = dataSource.getConnection();
Statement stmt = connection.createStatement())
connection.setAutoCommit(false);
stmt.execute(String.format("INSERT INTO city VALUES (9999, 'Darko town', '123')"));
connection.rollback();
catch (SQLException e)
Assert.fail("Exception " + e);
执行此操作后,城市将从数据库中删除。
我的真实测试场景:
@Test
@Transactional
public void testDeleteDocuments()
try (final Connection connection = deletionService.getDataSource().getConnection();
Statement stmt = connection.createStatement())
connection.setAutoCommit(false);
deletionService.startHacDeletion();
connection.rollback();
catch (SQLException e)
Assert.fail("Exception " + e);
通过我正在测试的方法完成的所有操作:DeletionService.startHacDeletion()
未还原。
我错过了什么吗?这是正确的方法吗?请帮忙....
更新:
这里是删除功能
public void deleteHacDocuments ()
List<Document> allComments = new ArrayList<>();
while (hacDeletionActive)
List<Document> parentDocuments = documentRepository.findHacDocuments();
LOG.info(String.format("Remove HAC parent documents %d", parentDocuments.size()));
for(Document document : parentDocuments)
LOG.info(String.format("Remove HAC documents %d", document.getId()));
if (parentDocuments.isEmpty())
hacDeletionActive = false;
LOG.info("HAC deletion finished");
else
for (Document doc : parentDocuments)
if (doc.getType() == 1)
deleteWholeStudy(doc.getId());
else if (doc.getType() == 6)
List<Document> studies = documentRepository.findStudiesByCase(doc.getId());
for (Document study : studies)
deleteWholeStudy(study.getId());
deleteWholeCase(doc.getId());
else if (doc.getType() == 4)
allComments.add(doc);
else
documentService.markDocumentAsDeleted(doc.getId());
documentService.markCommentsAsDeleted(allComments);
【问题讨论】:
在您解释startHacDeletion
的作用之前,无法判断。
它做了很多事情。通过更改数据库中的某些字段来更改某些域类。
这么多东西可能是更改没有回滚的原因。在给出更多信息之前,无法确定。
检查问题的更新
您是否在使用 Truncate 或 drop 之类的查询?
【参考方案1】:
我对 Micronaut 框架不是很熟悉,也不太明白如果手动回滚更改,为什么需要 @Transactional
注释。
但是从您的示例中可以明显看出,在第一种情况下,您使用connection
创建一个用于执行查询的statement
,然后在同一个connection
上调用回滚。
在第二种情况下,您从DataSource
获得connection
,但您没有将它传递给服务以使用它,因此如果DataSource
使用某个连接池并且并不总是返回相同的连接,则服务将从它那里获得另一个connection
,而不是你要回滚的那个。
这是我在您的代码中看到的唯一可能的问题,如果我的回答不能帮助解决您的问题,请提供a minimal, reproducible example。
【讨论】:
【参考方案2】:Dbunit 是 JUnit 用于数据库测试的特殊扩展 http://dbunit.sourceforge.net/howto.html
JUnit 本身并不是为与数据库一起工作而设计的,因此,您遇到了这个问题并考虑了一个复杂的解决方案。
【讨论】:
【参考方案3】:不完全相同的用例,因为我使用 Spock 进行测试,但我很确定 JUnit 中存在类似以下内容。
在每次将一些数据写入数据库的测试中,我所做的是执行一个cleanup
块,该块会删除所有创建的数据。
为了确保我们不会忘记删除测试中创建的所有内容并污染其他测试,我们有一个父 cleanup
,它在每次测试后执行,并确保数据库中没有数据。基本上运行select count(*) from xxxxx
,如果有数据则测试失败。
如前所述,这不是您问题的真正答案,而是您可以遵循的不同方法。它对我们来说非常有效。
【讨论】:
【参考方案4】:根据您使用的测试库,您需要设置和拆除测试数据。 将 Datasource 注入到 Test 类中,并使用 datasource.connection 执行查询以清理数据。
【讨论】:
【参考方案5】:用@MicronautTest
注释你的休息类,它会默认进行回滚。摆脱你正在做的所有尝试/捕获连接的东西。您不需要显式回滚您的连接。在此处查看示例:https://github.com/micronaut-projects/micronaut-test/blob/master/test-junit5/src/test/java/io/micronaut/test/junit5/JpaRollbackTest.java
【讨论】:
我的课程使用@MicronautTest 进行了注释。似乎没有帮助....以上是关于Micronaut 和 JUnit 回滚的主要内容,如果未能解决你的问题,请参考以下文章