我在尝试将 Hibernate 事务中所做的更改推送到数据库以使 DbUnit 在我的测试用例中正常工作时遇到问题。似乎 DbUnit 没有看到 Hibernate 所做的更改,因为它们尚未在事务结束时提交......而且我不确定如何重组我的测试用例以使其正常工作。
这是我过度简化的测试用例来证明我的问题:-
@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 相同的事务和连接。
我找到了 Transaction aware datasource (use dbunit & hibernate in spring)对此进行解释的博文。
另一种方法是完全跳过事务测试并手动清理数据库。查看我的 transactional tests considered harmful文章。
关于java - 让 DbUnit 与 Hibernate 事务一起工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8591487/