【问题标题】:How to test rollback of transaction in Hibernate+Spring+JUnit如何在 Hibernate+Spring+JUnit 中测试事务的回滚
【发布时间】:2016-01-11 06:02:51
【问题描述】:

我正在尝试测试回滚事务的机制,以防出现问题。我阅读了许多类似的主题,但没有任何帮助。这是我尝试的:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "file:src/main/webapp/WEB-INF/rest-servlet.xml" })
@Transactional
public class TagDaoImplTest extends DatabaseTestCase {

    private static final String FLAT_XML_DATASET = "FlatXmlDataSet.xml";

    @Autowired
    private TagDao tagDao;
    @Autowired
    private SessionFactory sessionFactory;

    @Before
    public void setUp() throws Exception {
        DatabaseOperation.REFRESH.execute(getConnection(), getDataSet());
    }

    @Test
    public void testAddWithRollback() throws Exception {
        addWithRollback("testTagToAdd"); //i suppouse that we tried to add, but somthing went wrong and transaction was rolled back
        final Tag testTagToAdd = tagDao.findByTag("testTagToAdd"); // so db must be without changes and i check this
        assertNull(testTagToAdd);
    }

    @Rollback(true) //i want this method to rollback after its work to imitate corrupted transaction
    private void addWithRollback(String tag) throws Exception {
        tagDao.add(new Tag(tag));
    }
}

我的 dao 是这样的:

@Repository("tagDao")
public class TagDaoImpl implements TagDao {

    @Override
    public void add(Tag tag) {
        final Session session = sessionFactory.getCurrentSession();
        session.persist(tag);
    }
}

但是我的测试失败了,因为它在 db 中找到了该标记(这意味着事务没有回滚)。我尝试了许多不同的方法,例如获取当前会话和事务并手动调用回滚,但没有任何反应。你能帮帮我吗?

【问题讨论】:

  • 您实际上有一个方法可以使回滚?或者如果一个方法有错误/异常,它会执行标准的休眠回滚? (最后一个意义不大,hibernate回滚已经测试过了,但是只要抛出需要的异常就可以轻松搞定)
  • 我也试过在dao类中抛出异常,让事务回滚,但还是能找到添加的标签。
  • 您的测试在单个事务中执行,该事务将在 testAddWithRollback 执行后回滚(或提交)
  • 好的,但是为什么 sessionFactory.getCurrentSession().getTransaction().rollback() 什么都不做,我仍然可以读取添加的标签?但是,我该如何更改它,在其 on 事务中运行每个方法,并测试是否以某种方式执行了回滚?

标签: java spring hibernate junit transactions


【解决方案1】:

首先,对我来说,尝试测试存储库层感觉有点奇怪。通常不应该有任何业务逻辑,因此这意味着您尝试测试已经测试过数百万次的 Hibernate 或 SQL,并且没有任何意义。

我建议用这样的方式注释你的方法:

@Transactional(rollbackFor=Exception.class) 

并且可能指定异常。然后在测试中,你准备好你的系统,让这个方法抛出这个异常。因此它应该被回滚并且不应该改变任何数据。

此外,我想补充一点,此时实际加载弹簧上下文很可能与生产环境不同。因此,这是一个额外的点,我会说没有这样做的意义。至少在存储库层。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-09
    • 2015-06-19
    • 2012-01-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多