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.
Asked
Active
Viewed 1,793 times
3
-
How are you accessing the database (Jpa/Hibernate/JdbcTemplate/...)? – slauth Aug 20 '21 at 09:39
-
Spring Data JPA – erlik Aug 20 '21 at 09:55
-
What about embedded db? https://stackoverflow.com/questions/2205126/starting-an-h2-database-server-from-maven – lojza Aug 20 '21 at 14:21
1 Answers
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