我有一些针对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);
}
}
}
我对Micronaut框架不是很熟悉,并且不真正理解如果手动回滚所做的更改,为什么需要@Transactional
注释。
但是从您的示例中显而易见,在第一种情况下,您使用connection
创建用于执行查询的statement
,然后在同一connection
上调用回滚。在第二种情况下,您从connection
获得了DataSource
,但没有将其传递给服务以使用它,因此,如果DataSource
使用某些连接池并且并不总是返回相同的连接,则该服务将从中获得另一个connection
,而不是您正在回滚的那个。
这是我在您的代码中看到的唯一可能的问题,如果我的回答不能帮助解决您的问题,请提供a minimal, reproducible example。
Dbunit是JUnit的特殊扩展,用于数据库测试http://dbunit.sourceforge.net/howto.html
JUnit本身并不是为与数据库一起使用而设计的,因此,您遇到了这个问题并正在思考一个复杂的解决方案。
不完全相同的用例,因为我使用Spock进行测试,但是我很确定JUnit中存在以下类似内容。
我在每次测试中将一些数据写入数据库的操作正在执行cleanup
块,该块将删除所有创建的数据。为确保我们不会忘记删除测试中创建的所有内容并污染其他测试,我们有一个父级cleanup
,它将在每次测试后执行,并确保数据库中没有数据。基本上运行select count(*) from xxxxx
,如果有数据,则测试失败。
如前所述,这不是您问题的真正答案,而是您可以采用的另一种方法。这对我们来说真的很好。
取决于所使用的测试库,您需要设置和拆卸测试数据。将数据源注入Test类,并使用datasource.connection执行查询以清理数据。
用@MicronautTest
注释您的rest类,默认情况下它将进行回滚。摆脱您正在执行的所有try / catch连接工作。您无需显式回滚连接。在此处查看示例:https://github.com/micronaut-projects/micronaut-test/blob/master/test-junit5/src/test/java/io/micronaut/test/junit5/JpaRollbackTest.java