I'm fairly new to Spring, and I'm trying to get integration testing working using AbstractTransactionalSpringContextTests, and I'm having problems figuring out how to test rollbacks.
Here is my understanding of how to use Spring's integration testing support:
- I can populate my database with data for the test in onSetUpInTransaction, and it will be rolled back after the test.
- Spring keeps my @Transactional methods from actually committing data to the database
- After my @Transactional methods are called (after I run the method to test), I can then test the data in the database within the same transaction
- When the test is done, Spring rolls the transaction back, leaving the database as it was before the test case started.
My problem is that when the method I'm testing throws an exception, Spring just marks the transaction for rollback, but doesn't actually do anything until after the test finishes, so when I test the data, it hasn't been rolled back yet, and the test fails.
Here's what the logs say:
At first I thought maybe I should call endTransaction() if an exception is thrown, so that the transaction is actually rolled back, but my test data was set up inside that same transaction, so it would be rolled back also.Code:... 2007-06-22 16:04:28,558 [main] DEBUG org.springframework.transaction.support.TransactionSynchronizationManager - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@6755b6] for key [org.hibernate.impl.SessionFactoryImpl@10b5064] bound to thread [main] 2007-06-22 16:04:45,936 [main] DEBUG org.springframework.transaction.interceptor.TransactionInterceptor - Completing transaction for [com.blah.CommunityManager.resendInvitations] after exception: java.lang.IllegalArgumentException: CommunityManager.resendInvitations() - invalid invitation 2007-06-22 16:04:45,936 [main] DEBUG org.springframework.transaction.interceptor.RuleBasedTransactionAttribute - Applying rules to determine whether transaction should rollback on java.lang.IllegalArgumentException: CommunityManager.resendInvitations() - invalid invitation 2007-06-22 16:04:45,936 [main] DEBUG org.springframework.transaction.interceptor.RuleBasedTransactionAttribute - Winning rollback rule is: null 2007-06-22 16:04:45,936 [main] DEBUG org.springframework.transaction.interceptor.RuleBasedTransactionAttribute - No relevant rollback rule found: applying superclass default 2007-06-22 16:04:45,936 [main] DEBUG org.springframework.orm.hibernate3.HibernateTransactionManager - Participating transaction failed - marking existing transaction as rollback-only 2007-06-22 16:04:45,951 [main] DEBUG org.springframework.orm.hibernate3.HibernateTransactionManager - Setting Hibernate transaction on Session [org.hibernate.impl.SessionImpl@2b7632] rollback-only 2007-06-22 16:05:16,507 [main] DEBUG org.springframework.transaction.support.TransactionSynchronizationManager - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@6755b6] for key [org.hibernate.impl.SessionFactoryImpl@10b5064] bound to thread [main] ...
What I'd like to do is be able to see that the data still looks like it did just before the method I'm testing gets called, but I don't see any way to do that, because the setup before the method and the method are really executing in a single transaction. There's no way to roll back just what the method did.
I guess I'd be ok with some other way of determining that the transaction is going to be rolled back. Is there a way to ask Spring if the exception will cause the transaction to rollback?
Anyway, I'm hoping someone can point me in the right direction on how to test rollbacks when an exception is thrown. Thanks in advance!
nathan


Reply With Quote