让DbUnit使用Hibernate事务

我在尝试将Hibernate事务中的更改推送到数据库以使DbUnit在我的测试用例中正常工作时遇到问题。 似乎DbUnit没有看到Hibernate所做的更改,因为它们还没有在事务结束时提交……而且我不确定如何重构我的测试用例以使其工作。

这是我过度简化的测试用例来certificate我的问题: –

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:applicationContext-test.xml" }) @TransactionConfiguration(transactionManager = "transactionManager") @Transactional public class SomeTest { @Autowired protected DataSource dataSource; @Autowired private SessionFactory sessionFactory; @Test public void testThis() throws Exception { Session session = sessionFactory.getCurrentSession(); assertEquals("initial overlayType count", 4, session.createQuery("from OverlayType").list().size()); //----------- // Imagine this block is an API call, ex: someService.save("AAA"); // But for the sake of simplicity, I do it this way OverlayType overlayType = new OverlayType(); overlayType.setName("AAA"); session.save(overlayType); //----------- // flush has no effect here session.flush(); assertEquals("new overlayType count", 5, session.createQuery("from OverlayType").list().size()); // pull the data from database using dbunit IDatabaseConnection connection = new DatabaseConnection(dataSource.getConnection()); connection.getConfig().setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new MySqlDataTypeFactory()); QueryDataSet partialDataSet = new QueryDataSet(connection); partialDataSet.addTable("resultSet", "select * from overlayType"); ITable actualTable = partialDataSet.getTable("resultSet"); // FAIL: Actual row count is 4 instead of 5 assertEquals("dbunit's overlayType count", 5, actualTable.getRowCount()); DataSourceUtils.releaseConnection(connection.getConnection(), dataSource); } } 

我使用DbUnit的全部想法是: –

  • 调用someService.save(...)将数据保存到多个表中。
  • 使用DbUnit从XML获取预期的表。
  • 使用DbUnit从数据库中获取实际表。
  • Assertion.assertEquals(expectedTable, actualTable);

但是,在这一点上,我无法让DbUnit看到Hibernate在事务中所做的更改。

我应该如何改变以使DbUnit与Hibernate事务很好地协作?

谢谢。

我从来没有使用过DbUnit,但似乎TransactionAwareDataSourceProxy可以解决这个问题。 基本上,您需要使用此代理包装原始数据源并使用它代替,以便此代码:

 new DatabaseConnection(dataSource.getConnection()) 

实际上通过代理并使用与Hibernate相同的事务和连接。

我发现了事务感知数据源(在spring使用dbunit和hibernate)博客文章解释了这一点。

另一种方法是完全跳过事务测试并手动清理数据库。 看看我的交易测试被认为是有害的 artcle。

看起来该测试用例需要两个事务:一个用于将数据放入数据库,另一个用于检索数据。

我会做的是:

  • 使用内存数据库,以便在unit testing结束时清理数据。
  • 删除事务注释并直接使用beginTransaction和commit方法。

初始overlaytype计数为0,保存会话后,它应为1。