2009-06-09 246 views
2

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

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

任何人都可以访问一个在数据库中工作和回滚信息的例子。

附注:
我的测试方法中的每个数据库操作都会回滚。但@Before方法中super.deleteFromTables("person")的执行没有从数据库中回滚所有以前的数据。

Spring会回滚所有的CRUD操作,但数据库在事务不回滚之前会清理干净。春季交易管理测试

+0

如果在调试中放置'org.springframework.transaction',日志输出中是否有任何有趣的内容? – 2009-06-10 06:24:28

回答

2

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

我忘记了关于数据库命令的教训,当您在DML语句后执行DDL语句时,它会自动提交事务。我在DML后执行了一个DDL,删除了所有记录,然后ALTERAUTO_INCREMENT表中的内容会导致自动提交并永久删除表中的所有记录。

解决我的问题解决我的问题。

0

避开你的问题,我建议你使用一个单独的数据库实例来运行你的测试。这样,您可以安全地擦拭干净,并根据需要进行测试初始化​​。

据我所知,数据库测试的Spring支持类只回滚测试中发生的情况,而不是在测试的设置和拆卸过程中发生的情况。

0

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

有了这个,你可以设置你的Hibernate属性“创建降”:

随着创建拖放,数据库架构 会当 显式关闭SessionFactory被丢弃。

参见:Optional Hibernate Config properites

例片段:

<bean id="sessionBean" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="hibernateProperties"> 
     <props> 
     <prop key="hibernate.hbm2ddl.auto">create-drop</prop> 
     ...etc 
0

虽然我跟那家伙的提示进行测试deciated分贝同意,没有任何理由使用填充分贝不该在事务上下文中执行@Before和@After方法都不起作用,因此应该对其进行回滚。

候选条件:

  • 的数据建立在做的东西是不是事务性的(即DDL语句)
  • 东西在您的测试实际上是犯

你能后的交易@Before方法,我只是想知道你是在清理表还是实际删除并重新创建它们?

+0

我使用Spring提供的测试机制。在我的`@ Before`方法中,`super.deleteFromTables(“members”);``super.executeSqlScript(“classpath:somescript.sql”,true);` – 2009-06-10 00:39:16

1

可能的原因:您正在使用的没有正确的交易数据库/数据库引擎

  • ;
  • 您正在使用多个事务管理器和/或数据源,并且没有找到正确的一个;
  • 你做你自己的,独立的,交易在测试类

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

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没有任何事务性设置(建议/编程),它依赖于调用者是事务性的 - 无论是生产服务还是测试;
  • 该测试不包含任何事务管理代码,因为它全部在框架中完成。
+0

我的DAO实现扩展了Spring提供的SimpleJdbcDaoSupport,数据库。我的DAO是否有交易管理代码?如果我的DAO有事务管理,我该如何测试它? – 2009-06-10 00:47:44

0

至于我可以告诉大家,通过查看AbstractJUnit4SpringContextTests时和TransactionalTestExecutionListener的Javadoc和源代码,你需要注释你的测试方法,你想用transactionalised @Transactional。

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

我建议你用所有这些注释创建注解的方法,包括@Before,然后用这些方法的断点运行测试。这样,您可以查看堆栈,并确定春天是否为您启动了交易。如果你在堆栈中看到类似“TransactionInterceptor”的东西,或者在名称中有“Transaction”的东西,那么很可能你正在进行一次交易。

1

我不确定你的班级有什么问题。这里是一个类的提取物,你想要用DbUnit和春季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); 


    } 
} 

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

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

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

希望这有助于

0

你正在做tx中的@Before方法中的super.deleteFromTables。所以如果回滚tx不删除也会回滚?