使用Spring Boot在每个Cucumber场景后回滚事务。

3

我正在使用Spring Boot 2.5的BDD测试框架Cucumber。 每次执行Cucumber场景后,我想回滚事务或重置数据库。我正在使用一个由动态生成数据填充的H2数据库。 我尝试过 @Transactional,但它不起作用,而 @DirtiesContext 太慢了。


你是通过哪种方式访问数据库的(Jpa / Hibernate / JdbcTemplate /...)? - slauth
Spring Data JPA - erlik
嵌入式数据库怎么样?https://dev59.com/eHE95IYBdhLWcg3wrP6w - lojza
1个回答

3
这可以通过使用PlatformTransactionManager来在每个场景之前开始一个事务,然后在其完成后回滚事务。当执行一个使用@Transactional注解的JUnit测试类时,这基本上就是TransactionalTestExecutionListener所做的。
在Cucumber中,您需要使用@Before@After钩子来实现此功能。因为您可能不希望为每个场景都这样做,所以您可以选择使钩子有条件地执行,这样它们只会在正确标记了场景时才被执行。
例如:
@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


我是这样做的,当在服务中使用 @Transactional 注释方法时,会创建并提交新的 TransactionStatus。我通过 TransactionAspectSupport 类进行调试。 - RenatoIvancic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接