Home > Net >  Why Quarkus @TestTransaction doesn't work?
Why Quarkus @TestTransaction doesn't work?

Time:06-24

I wrote the test for Quarkus and expect that after test there were not any new raws in database after Test. But raws appear after every test.

Quarkus 2.10.0 JUnit 5 Java 17

@QuarkusTest
public class IssueChangeConsumerTests {

    @Inject
    private JiraChangeConsumer sut;

    @Inject
    private JiraStatusDao dao;

    @org.junit.jupiter.api.Test
    @TestTransaction()
    public void test(){
        JiraStatusDTO statusDTO = new JiraStatusDTO(ISSUE_ID, CHANGE_ID, PROJECT_KEY, ISSUE_NUM, OLD_STATUS, NEW_STATUS, CHANGE_DATE_TIME);
        JiraChangeDTO change = new JiraChangeDTO(statusDTO, null, null);
        sut.consumeJiraChange(change);

        List<JiraStatusChange> issuesChanges = dao.getIssuesChanges(PROJECT_KEY, List.of(ISSUE_NUM));
        assertThat(issuesChanges)
                .extracting(
                        JiraStatusChange::getIssueId,
                        JiraStatusChange::getChangeId,
                        JiraStatusChange::getProjectKey,
                        JiraStatusChange::getIssueNum,
                        JiraStatusChange::getChangeDateTime,
                        JiraStatusChange::getNewStatus,
                        JiraStatusChange::getOldStatus)
                .contains(new Tuple(ISSUE_ID, CHANGE_ID, PROJECT_KEY, ISSUE_NUM, dt, NEW_STATUS, OLD_STATUS));
    }
}

CodePudding user response:

On processors level I have put annotation

@Transactional(value = Transactional.TxType.REQUIRES_NEW)

And this annotation disabled

@TestTransaction

When I changed to

@Transactional(value = Transactional.TxType.MANDATORY)

It started to work.

CodePudding user response:

The @TestTransaction will only rollback commits made inside it's scope.

If you call another method that is annotated with @Transactional, this commit won't be undone.

Example

@Test
@TestTransaction
public void test() {
    client.persist();
}

In the above example, if the persist method doesn't have one @Transactional annotation, the changes in the database will suffer rollback in the end of the test() method.

Workaround

One workaround I'm doing, when I must test methods that have the @Transactional annotation, is to create one class on the test package and put all the DELETEs needed there. The idea is to run this deletion method on the beginning of the tests that need clean tables.

In my case I'm using one in memory database on my tests, that is H2.

package org.acme.tests;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.transaction.Transactional;

@ApplicationScoped
public class CleanTables {

  @Inject
  EntityManager entityManager;

  @Transactional
  public void clean() {
    entityManager.createNativeQuery("DELETE FROM YOUR_SCHEMA.YOUR_TABLE_A").executeUpdate();

    entityManager.createNativeQuery("DELETE FROM YOUR_SCHEMA.YOUR_TABLE_B").executeUpdate();
  }

}

Transactional annotation

Just to clarify, all methods annotated with @Transactional will send a commit when they finish successfully.

  • Related