2010-11-02 48 views
2

我正在为我的DAO编写一些测试,并且因为很多测试使用了保存到我的数据库的测试对象,我创建了一个setup()和teardown()方法(注释@Before和@After)以避免多余的代码,但其中一个测试,实际上并不需要测试对象的一个​​测试,在DAO中调用一个包含调用getCurrentSession()的方法。这是一种使用ScrollableResults从批处理中获取数据的方法,并且避免内存填满每50行调用flush()和clear()的方法。这就产生了一个问题,因为清()实际上消除了在从会话建立()创建的测试对象,所以当拆除()被调用我得到一个错误:@Before和@After排除

 
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [nl.ru.cmbi.pdbeter.core.model.domain.PDBEntry#395] 

有没有一种办法告诉JUnit不要在这个测试中使用setup()和teardown(),还是把所有不需要setup()和teardown()的测试放在新的测试类中更好?

回答

6

首先是的,在单独的测试中隔离不需要@Before@After行为的测试是非常有意义的。其次,你可能想看看Spring Framework's support for running unit tests within a database transaction,它会在每次测试结束时自动回滚,这样你就不必担心一些测试会影响外部资源的状态,或者询问关于在每个订单中运行哪些测试的问题等。将其与内存数据库(如HSQL)结合使用,您甚至不需要担心运行的数据库可能会运行,从而使您的构建更加便携。

+0

感谢您的快速回答!然后,我将创建一个新的测试课程。而且我已经在使用spring的事务中运行测试;) – FinalArt2005 2010-11-02 13:50:28

2

JUnit会运行与@Before@After注释每个测试,所以你需要将你的测试分为两个类的所有方法。

0

定义自己的BlockJUnit4ClassRunner:

public class WithoutBeforeAfter extends BlockJUnit4ClassRunner { 

    public WithoutBeforeAfter(Class<?> klass) throws InitializationError { 
     super(klass); 
    } 

    @Override 
    protected Statement withBefores(FrameworkMethod method, Object target, Statement statement) { 
     if(method.getName().equals("[email protected]")){ 
      return statement; 
     }else{ 
      return super.withBefores(method, target, statement); 
     } 
    } 

    @Override 
    protected Statement withAfters(FrameworkMethod method, Object target, Statement statement) { 
     if(method.getName().equals("[email protected]")){ 
      return statement; 
     }else{ 
      return super.withAfters(method, target, statement); 
     } 
    } 
} 

然后在你的测试用例中使用它:

@RunWith(value=WithoutBeforeAfter.class) 

至少它可以使用JUnit 4.8。

相关问题