3

I'm using the BDD testing framework Cucumber with Spring Boot 2.5. I want to rollback transactions or reset my database after each Cucumber scenarios. I'm using an H2 database, populate by dynamically generated data. I tried @Transactional, but it doesn't work and @DirtiesContext is to slow.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
erlik
  • 33
  • 4

1 Answers1

3

The way to do this is to use the PlatformTransactionManager to start a transaction before each scenario and to roll it back after. This is essentially what TransactionalTestExecutionListener does when a JUnit test class annotated with @Transactional is executed.

In Cucumber you would do this using @Before and @After hooks. And because you may not want do this for every scenario you can choose to make the hooks conditional so that they only execute when a scenario is tagged in the right way.

For example:

@txn
Feature: Search

  Background:
    Given there is a user

  Scenario: Find messages by content
    Given a User has posted the following messages:
      | content            |
      | I am making dinner |
      | I just woke up     |
      | I am going to work |
    When I search for "I am"
    Then the results content should be:
      | I am making dinner |
      | I am going to work |
public class SpringTransactionHooks implements BeanFactoryAware {

    private BeanFactory beanFactory;
    private TransactionStatus transactionStatus;

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }

    @Before(value = "@txn", order = 100)
    public void startTransaction() {
        transactionStatus = beanFactory.getBean(PlatformTransactionManager.class)
                .getTransaction(new DefaultTransactionDefinition());
    }
    
    @After(value = "@txn", order = 100)
    public void rollBackTransaction() {
        beanFactory.getBean(PlatformTransactionManager.class)
                .rollback(transactionStatus);
    }

}

From:

https://github.com/cucumber/cucumber-jvm/tree/main/examples/spring-java-junit5

M.P. Korstanje
  • 10,426
  • 3
  • 36
  • 58
  • I did it that way, while in the service annotated method with @Transactional new TransactionStatus gets created and commited. I am debugging it through `TransactionAspectSupport` class. – RenatoIvancic Dec 04 '22 at 19:45