spring - 如何测试Spring事务

标签 spring spring-boot spring-data-jpa spring-data spring-transactions

我正在使用 Spring Boot 2.1.0 开发一个项目,我遇到了以下情况。

我有以下存储库

@Repository
public interface ActivityRepository extends PagingAndSortingRepository<Activity, Long> {

    @Transactional
    @Modifying
    @Query("") // Imagine a query
    void updateBacklogStatusAge();

    @Transactional
    @Modifying
    @Query("QUERY 2") // Imagine a query
    void updateNextStatusAge();

    @Transactional
    @Modifying
    @Query("QUERY 3") // Imagine a query
    void updateInProgressStatusAge();
}

和以下组件

@Component
public class ColumnAgeJob {

    private final ActivityRepository activityRepository;

    public ColumnAgeJob(final ActivityRepository pActivityRepository) {
        activityRepository = pActivityRepository;
    }

    @Transactional
    public void update() {
        activityRepository.updateBacklogStatusAge();
        activityRepository.updateNextStatusAge();
        activityRepository.updateInProgressStatusAge();
    }
}

现在我想测试事务注解是否有效。

基本上我的目标是检查在 updateInProgressStatusAge() 调用期间引发的 runtimeException 是否会导致 updateNextStatusAge 和 updateBacklogStatusAge 修改的回滚。

我该怎么做? 谢谢

最佳答案

您可以使用 Mockito 通过使用 @SpyBean 或 @MockBean 来更改您的服务或存储库的行为。

不幸的是@SpyBean 不能在 JPA 存储库上工作(https://github.com/spring-projects/spring-boot/issues/7033,这个问题是针对 Spring boot 1.4.1,但我对 2.0.3.RELEASE 有同样的问题)

作为解决方法,您可以创建一个测试配置来手动创建您的模拟:

@Configuration
public class SpyRepositoryConfiguration {

   @Primary
   @Bean
   public ActivityRepository spyActivityRepository(final ActivityRepository real) 
      return Mockito.mock(ActivityRepository.class, AdditionalAnswers.delegatesTo(real));
   }
}

在你的测试中:

@Autowired
private ActivityRepository activityRepository;
....
@Test
public void testTransactional() {
    Mockito.doThrow(new ConstraintViolationException(Collections.emptySet())).when(activityRepository).updateInProgressStatusAge();

    activityRepository.updateBacklogStatusAge();
    activityRepository.updateNextStatusAge();
    activityRepository.updateInProgressStatusAge();

    // verify that rollback happens
}

关于spring - 如何测试Spring事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53380923/

相关文章:

java - Jar 文件 ADD DIRECTORY ENTRIES 导出 jar 时的 Eclipse 选项

spring - 在 Spring Data JPA 中以 3 种不同的方式创建查询

java - spring-boot-starter-data-jpa @OneToMany 在更新时不会插入新的子项

java - Spring Data CrudRepository 只读取(它不保存、更新或删除)

ruby-on-rails - Rails 服务器工作,Rails 控制台不工作。 `require' : cannot load such file -- bundler/setup (LoadError) -

java - response.sendError 使用自定义过滤器抛出异常

java - Oracle 序列 - 'increment by' 和 'cache'

java - @GetMapping 和 RSocketServer 与 spring-boot-starter-rsocket

Spring Data Rest用户存储库BCCrypt密码

java - 与 RabbitMQ 的模拟连接