Откат Micronaut и JUnit - PullRequest
       36

Откат Micronaut и JUnit

4 голосов
/ 09 января 2020

У меня есть несколько тестов, написанных для микросервиса микро-службы. Я хотел бы, чтобы после моих тестов все изменения в БД были отменены (откат). Во-первых, я написал простой пример, который, кажется, работает. Изменения отменены. Но когда я запускаю тест микросервиса по той же аналогии, изменения не возвращаются.

Простой рабочий пример:

@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);
        }

}
}

Ответы [ 5 ]

0 голосов
/ 19 января 2020

Аннотируйте ваш класс отдыха с помощью @MicronautTest, и он по умолчанию выполнит откат. Избавьтесь от всего, что вы делаете, пытаясь поймать соединение. Вам не нужно явно откатывать ваше соединение. Смотрите пример здесь: https://github.com/micronaut-projects/micronaut-test/blob/master/test-junit5/src/test/java/io/micronaut/test/junit5/JpaRollbackTest.java

0 голосов
/ 17 января 2020

В зависимости от того, какую библиотеку тестирования вы используете, вам нужно установить и разорвать тестовые данные. Вставьте источник данных в класс Test и используйте datasource.connection для выполнения запросов для очистки данных.

0 голосов
/ 15 января 2020

Dbunit - это специальное расширение для JUnit для тестирования базы данных http://dbunit.sourceforge.net/howto.html

Сам JUnit не предназначен для работы с базой данных, поэтому вы столкнулись с этой проблемой и подумали о комплексное решение.

0 голосов
/ 15 января 2020

Не совсем тот же вариант использования, потому что я использую Spock для тестирования, но я почти уверен, что в JUnit существует что-то вроде следующего.

Что я делаю в каждом тесте, который записывает некоторые данные в базу данных, так это выполнение блока cleanup, который удаляет все созданные данные. Чтобы мы не забыли удалить все созданные в тесте и загрязнять другие тесты, у нас есть родительский элемент cleanup, который выполняется после каждого теста и гарантирует, что в базе данных нет данных. Обычно запускайте select count(*) from xxxxx, и если там есть данные, тест не пройден.

Как упоминалось ранее, это не реальный ответ на ваш вопрос, а другой подход, которому вы могли бы следовать. Это работает очень хорошо для нас.

0 голосов
/ 14 января 2020

Я не очень знаком с инфраструктурой Micronaut и не очень понимаю, зачем нужна аннотация @Transactional, если вы откатываете изменения вручную.

Но что очевидно из ваших примеров, что в В первом случае вы используете connection для создания statement, который используется для выполнения запроса, а затем вызываете откат для того же connection. Во втором случае вы получаете connection от DataSource, но вы не передаете его службе, чтобы использовать его, поэтому, если DataSource использует некоторый пул соединений и не всегда возвращает одно и то же соединение, служба получит еще один connection от него, а не тот, который вы откатываете.

Это единственная возможная проблема, которую я вижу в вашем коде, если мой ответ не поможет решить вашу проблему, укажите минимальный воспроизводимый пример .

...