Question

I wonder how can I make unittest to ensure that all my DAOs have propagation=MANDATORY. I have implemented just a unit test to call dao.getAll() without a transaction, and fail if there was no exception. But this is not kind of full test, I can't check it for all child methods.

That's what I have now:

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
    }
}

Are there possibility just to check that all DAO methods are proxified with needed transaction propagation? Maybe to use reflection?

Was it helpful?

Solution

I usually do it using the following JUnit Test Case:

/**
 * 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()));
}

It checks that all the beans annotated with @Service are marked as Transactional too. I use the String Builder to be able to know which beans are missing the annotation.

OTHER TIPS

This can be done with an assertion utility method that uses TransactionSynchronizationManager class.

Check methods like TransactionSynchronizationManager.getCurrentTransactionIsolationLevel and ´isActualTransactionActive´.

It´s possible to get the transaction resource from the thread bound resource map, see the code for JtaTransactionManager and OpenEntityManagerInViewListener classes in spring source code.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top