嗨,我有一个单元测试应该测试一个cronjob
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "file:WebContent/WEB-INF/applicationContext.xml" })
@TransactionConfiguration(transactionManager = "hibernateTransactionManager")
@Transactional
public class cronTest {}
但由于交易,cronjob没有看到测试数据。但当我删除@Transactional时,Hibernate说:
org.hibernate.HibernateException: No Session found for current thread
当我自己承诺时
sessionFactory.getCurrentSession().getTransaction().commit();
sessionFactory.getCurrentSession().beginTransaction();
最后测试失败
org.springframework.transaction.TransactionSystemException: Could not commit Hibernate transaction; nested exception is org.hibernate.TransactionException: Transaction not successfully started
如何在没有交易的情况下进行单元测试?
测试的确如此:
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));
它检查过期角色的自动保护是否有效,石英作业每5秒运行一次
答案 0 :(得分:1)
通常我建议对可在单个事务中测试的代码使用单元测试,并使用集成测试(调出整个系统并执行您要测试的序列)来测试多事务行为。
但要回答这个问题:解决这个问题的一种方法是从测试方法中删除@Transaction,但是不要让测试方法直接控制事务,而是允许您正在测试的方法开始/提交他们自己的交易(他们通常会这样做,对吗?)
例如,我们可能会通过正常的DAO工作流进行测试,并且每个DAO方法都标记为@Transactional。每个方法都控制自己的事务提交,因此我们可以在单个测试方法中测试多事务行为。该测试可能如下所示:
// no @Transactional here, dao methods are @Transactional
public void testMultiTransactionUpdate() {
Entity t = dao.getEntity(id);
t.setProperty("somethingnew");
dao.update(t);
Entity t2 = dao.getEntity(id);
Assert.assertEquals(t1.getProperty(), t2.getProperty());
}
要注意的一件事是,如果您要提交内存数据库(如HSQLDB),则在一次测试中所做的更改将不会自动回滚,并且通常对后续测试可见。您必须在测试结束时手动撤消所有更改,或确保您的测试数据不会干扰其他不太容易的测试。这就是我谨慎使用这种技术的原因。