春季交易管理测试

我想使用SpringContextTests测试我的Dao类。
在我的方法类中,我扩展了AbstractTransactionalJUnit4SpringContextTests ,以便我的测试类与JUnit4集成。 我还设置了配置,并在@After中的@Before和tearDown中清理初始化和数据库。 我的测试类很完美。

我的问题是,当我运行我的测试类并且数据库充满了数据时,原始数据没有回滚,我的数据库被清除。 在@Before方法中,我清除数据库并填充数据,认为我将能够回滚它,但事实并非如此。

任何人都可以找到一个可以在数据库中工作和回滚信息的示例。

ADDONS:
我的测试方法中的每个数据库操作都会被回滚。 但是在@Before方法中执行super.deleteFromTables("person")并没有回滚数据库中的所有先前数据。

Spring回滚所有CRUD操作,但在事务不回滚之前清理数据库。

感谢所有回答我问题的人。 我从那些答案中学到了很多东西,但它并没有解决我的问题。
我知道我的测试数据可以进行事务管理,并且可以正常工作。
这个错误就在我身上。

我忘记了有关数据库命令的教训,当您在DML语句之后执行DDL语句时,它将自动提交事务。 我在DML之后通过删除所有记录来执行DDL,然后ALTER表中的AUTO_INCREMENT ,其中将导致自动提交并永久删除表的所有记录。

固定情景解决了我的问题。

可能的原因:

  • 你正在使用没有正确交易的数据库/数据库引擎;
  • 您正在使用多个事务管理器和/或数据源,并且未选择正确的事务管理器和/或数据源;
  • 你在测试类中做自己独立的事务

至于一个例子,这里是一个(我的头顶,没有编译)

 public class DBTest extends AbstractTransactionalJUnit4SpringContextTests { @Autowired private SomeDAO _aBeanDefinedInMyContextFile; @Test public void insert_works() { assert _aBeanDefinedInMyContextFile.findAll() == 0; _aBeanDefinedInMyContextFile.save(new Bean()); assert _aBeanDefinedInMyContextFile.findAll() == 1; } } 

关键点:

  • SomeDAO是一个接口,对应于在我的上下文中声明的bean;
  • bean没有任何事务设置(通知/程序),它依赖于调用者是事务性的 – 生产中的服务,或者我们情况下的测试;
  • 测试不包括任何事务管理代码,因为它都是在框架中完成的。

我不确定你class上有什么问题。 以下是使用dbunit和spring 2.5执行所需操作的类的摘录:

 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations={ "testContext.xml"}) @TransactionConfiguration @Transactional public class SampleDAOTest { @Autowired private DataSource dataSource; @Autowired private SampleDAO sampleDAO; @Before public void onSetUpInTransaction() throws Exception { //Populate Test data IDatabaseConnection dbUnitCon = new DatabaseConnection(DataSourceUtils.getConnection(dataSource), "DATASOURCE"); //read in from a dbunit excel file of test data IDataSet dataSet = new XlsDataSet(new File("src/test/resources/TestData.xls")); DatabaseOperation.INSERT.execute(dbUnitCon, dataSet); } @Test public void testGetIntermediaryOrganisation() { // Test getting a user User object = sampleDAO.getUser(99L); assertTrue(object.getValue); } } 

这种方法的一个好处是你不需要扩展任何类。 因此,您仍然可以拥有自己的测试层次结构。

如果你真的想坚持使用当前的方法而不是使用@before注释我的thinnk,你需要覆盖下面的方法并将你的设置代码放在那里。

 @Override public void onSetUpInTransaction() throws Exception {...} 

希望这可以帮助

对于你的问题,我建议你使用一个单独的数据库实例来运行你的测试。 这样,您可以安全地擦除它并让测试根据需要进行初始化。

据我所知,用于数据库测试的Spring支持类仅回滚测试中发生的事情,而不是在测试的设置和拆除中发生的事情。

同意Confusion–您应该针对自己的数据库模式运行测试。

有了这个,你可以将你的hibernate属性设置为’create-drop’:

使用create-drop,当SessionFactory显式关闭时,将删除数据库模式。

请参阅: 可选的Hibernate配置

示例代码段:

     create-drop ...etc 

虽然我同意这个人建议使用decored db进行测试,但没有任何理由说使用填充的db不起作用,@ Before和@After方法都在事务上下文中执行,因此应该有更改回滚。

候选条件:

  • 数据设置正在执行非事务性的操作(即DDL语句)
  • 测试中的某些内容实际上是在提交事务

你可以发布@Before方法,我只是想知道你是在清理表还是实际丢弃并重新创建它们?

据我所知,通过查看AbstractJUnit4SpringContextTests和TransactionalTestExecutionListener的Javadocs和源代码,您需要注释要与@Transactional进行事务处理的测试方法。

还有@BeforeTransaction和@AfterTransaction注释,您可以更好地控制事务中运行的内容。

我建议你创建带有所有这些注释的方法,包括@Before,然后在这些方法中使用断点运行测试。 通过这种方式,您可以查看堆栈并确定spring是否已为您启动了事务。 如果您在堆栈中看到类似“TransactionInterceptor”的内容,或者名称中包含“Transaction”的任何内容,那么您很可能正在进行交易。

你在@Before方法中做了super.deleteFromTables,它位于tx内。 那么如果tx被回滚,那么删除也不会被回滚吗?