如何在Hibernate+Spring+JUnit中测试事务回滚

6

我正在尝试在某些出错情况下测试事务回滚机制。我阅读了许多类似的主题,但没有什么能帮助我。以下是我的尝试:

@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);
    }
}

但我的测试失败了,因为它在数据库中找到了那个标签(这意味着事务没有回滚)。我尝试了许多不同的方法,比如获取当前会话和事务,并手动调用回滚,但是没有任何效果。你能帮我吗?


你们实际有一个进行回滚的方法吗?或者如果一个方法出现错误/异常,它会执行标准的Hibernate回滚吗?(最后一个并没有太多意义,Hibernate回滚已经被测试过了,但可以通过简单地抛出所需的异常来轻松完成) - Jordi Castilla
我也尝试在dao类中抛出异常,以使事务回滚,但它仍然可以找到添加的标签。 - KeLsTaR
您的测试执行在一个单一的事务中,该事务将在testAddWithRollback执行后回滚(或提交)。 - JEY
好的,但是为什么sessionFactory.getCurrentSession().getTransaction().rollback()没有任何作用,我仍然可以读取添加的标签?然而,我该如何更改它,以便每个单独的方法在其自己的事务中运行,并测试回滚是否以某种方式执行? - KeLsTaR
1个回答

1
首先,对我而言,您试图测试存储库层有点奇怪。通常不应存在任何业务逻辑,因此这意味着您试图测试已经被测试了数百万次的Hibernate或SQL,这是没有必要的。
我建议将您的方法注释为以下格式:
@Transactional(rollbackFor=Exception.class) 

可能需要指定异常。然后在测试中,您可以以这种方式准备系统,使该方法抛出此异常。因此,它应该被回滚,不应更改任何数据。

此外,我想补充的是,实际上在此时加载Spring上下文与生产环境中的情况很可能不同。因此,在存储库层面上至少没有必要这样做。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接