Micronaut和JUnit回滚

问题描述 投票:3回答:5

我有一些针对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);
        }

}
}
java testing junit rollback micronaut
5个回答
0
投票

我对Micronaut框架不是很熟悉,并且不真正理解如果手动回滚所做的更改,为什么需要@Transactional注释。

但是从您的示例中显而易见,在第一种情况下,您使用connection创建用于执行查询的statement,然后在同一connection上调用回滚。在第二种情况下,您从connection获得了DataSource,但没有将其传递给服务以使用它,因此,如果DataSource使用某些连接池并且并不总是返回相同的连接,则该服务将从中获得另一个connection,而不是您正在回滚的那个。

这是我在您的代码中看到的唯一可能的问题,如果我的回答不能帮助解决您的问题,请提供a minimal, reproducible example


0
投票

Dbunit是JUnit的特殊扩展,用于数据库测试http://dbunit.sourceforge.net/howto.html

JUnit本身并不是为与数据库一起使用而设计的,因此,您遇到了这个问题并正在思考一个复杂的解决方案。


0
投票

不完全相同的用例,因为我使用Spock进行测试,但是我很确定JUnit中存在以下类似内容。

我在每次测试中将一些数据写入数据库的操作正在执行cleanup块,该块将删除所有创建的数据。为确保我们不会忘记删除测试中创建的所有内容并污染其他测试,我们有一个父级cleanup,它将在每次测试后执行,并确保数据库中没有数据。基本上运行select count(*) from xxxxx,如果有数据,则测试失败。

如前所述,这不是您问题的真正答案,而是您可以采用的另一种方法。这对我们来说真的很好。


0
投票

取决于所使用的测试库,您需要设置和拆卸测试数据。将数据源注入Test类,并使用datasource.connection执行查询以清理数据。


0
投票

@MicronautTest注释您的rest类,默认情况下它将进行回滚。摆脱您正在执行的所有try / catch连接工作。您无需显式回滚连接。在此处查看示例:https://github.com/micronaut-projects/micronaut-test/blob/master/test-junit5/src/test/java/io/micronaut/test/junit5/JpaRollbackTest.java

© www.soinside.com 2019 - 2024. All rights reserved.