Hi I have a unit test which should test a cronjob
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "file:WebContent/WEB-INF/applicationContext.xml" })
@TransactionConfiguration(transactionManager = "hibernateTransactionManager")
@Transactional
public class cronTest {}
but due to the transaction the cronjob doesn’t see the data of the test. But when I remove the @Transactional Hibernate says:
org.hibernate.HibernateException: No Session found for current thread
when I commit by my own
sessionFactory.getCurrentSession().getTransaction().commit();
sessionFactory.getCurrentSession().beginTransaction();
the test fails at the end
org.springframework.transaction.TransactionSystemException: Could not commit Hibernate transaction; nested exception is org.hibernate.TransactionException: Transaction not successfully started
How can I get an unit test without transaction?
the Test does someting like that:
userDao.clear();
loadeduser = userService.getUserById(createUser.getUserID());
assertTrue(loadeduser.getAuthoritiesEntities().contains(adminRole));
assertTrue(loadeduser.getAuthoritiesEntities().contains(userRole));
// Wait for auto unsign
TestUtils.sleep(10000);
userDao.clear();
loadeduser = userService.getUserById(createUser.getUserID());
assertFalse(loadeduser.getAuthoritiesEntities().contains(adminRole));
assertTrue(loadeduser.getAuthoritiesEntities().contains(userRole));
it checks if the auto unsign of expired roles works, the quartz job runs every 5 secs
Typically I’d recommend using unit tests for code that can be tested within a single transaction, and integration tests (bringing up the full system and exercising the sequence you want to test) to test multi-transactional behavior.
But to answer the question: One way around this is to remove the @Transaction from the test method as you’ve done, but instead of making the test method control transactions directly, allow the methods you’re testing to begin/commit their own transactions (which they will normally be doing anyway, right?)
For instance, we might have tests that run through a normal DAO workflow, and each DAO method is marked as @Transactional. Each method controls its own transaction commits, so we can test multi-transactional behavior in a single test method. That test might look like this:
One thing to be careful of is that if you are committing against an in-memory database (like HSQLDB), your changes made in one test will not be automatically rolled back and will normally be visible to subsequent tests. You will have to manually undo all of your changes at the end of the test, or ensure that your test data does not interfere with other tests which is not so easy. That’s why I would use this technique sparingly.