如何对春天@Transactional进行单元测试?

时间:2014-02-13 14:34:14

标签: spring unit-testing transactions spring-transactions

我想知道如何进行单元测试以确保我的所有DAO都有propagation=MANDATORY。 我只实现了一个单元测试来在没有事务的情况下调用dao.getAll(),如果没有异常就失败。但这不是一种完整的测试,我无法检查所有子方法。

这就是我现在所拥有的:

String[] beanNamesForType = applicationContext.getBeanNamesForType(Dao.class);
for (String beanName : beanNamesForType) {
    Dao bean = (Dao) applicationContext.getBean(beanName);

    try {
        bean.getAll();
        fail();
    } catch (IllegalTransactionStateException ex) {
        //This is expected
    }
}

是否有可能只检查所有DAO方法是否与所需的事务传播相关联?也许用反射?

2 个答案:

答案 0 :(得分:3)

我通常使用以下JUnit测试用例来执行此操作:

/**
 * Test if all the @Services bean are annotated with the @Transactional
 * annotation.
 */
@Test
public void testServicesTransactionalAnnotations(){
    String[] beansNames = applicationContext.getBeanDefinitionNames();
    StringBuilder sb = new StringBuilder();
    for(String beanName : beansNames){
        Service serviceAnnotation = applicationContext.findAnnotationOnBean(beanName, Service.class);
        if(serviceAnnotation != null && applicationContext.findAnnotationOnBean(beanName,
                Transactional.class) != null){
            Transactional transactional = applicationContext.findAnnotationOnBean(beanName,
                    Transactional.class);
            if(!transactional.propagation().equals(Propagation.MANDATORY)){
                sb.append("Missing @Transactional Annotation in bean:").append(beanName).append("\n");
            }
    }
    Assert.assertTrue(sb.toString(), StringUtils.isBlank(sb.toString()));
}

它检查所有使用@Service注释的bean是否也标记为Transactional。我使用String Builder来了解哪些bean缺少注释。

答案 1 :(得分:0)

这可以使用使用TransactionSynchronizationManager类的断言实用程序方法来完成。

检查TransactionSynchronizationManager.getCurrentTransactionIsolationLevel和'isActualTransactionActive'等方法。

可以从线程绑定资源映射中获取事务资源,请参阅spring源代码中的JtaTransactionManager和OpenEntityManagerInViewListener类的代码。