2010-05-26 33 views
2

我正在用Spring和JUnit测试我的Hibernate DAO。Spring和JUnit注释测试:在单独的事务中创建灯具

我希望每个测试方法都以预填充的数据库开始,即Java对象已保存在数据库中的已经提交的Hibernate事务中。我怎样才能做到这一点?

使用@After和@Before,方法在与使用@Test和@Transactional装饰的方法相同的Hibernate事务中执行(实际测试方法启动时不会刷新第一级缓存)。 @BeforeTransaction和@AfterTransaction显然不能用于Hibernate,因为即使用@Transactional和@ Before/AfterTransaction之外的方法来标注方法,它们也不会创建事务。

有什么建议吗?

回答

4

一种方法可能是将您的初始化逻辑外部化为外部服务,而事务性方法是从您的@BeforeTransaction和@AfterTransaction注释的方法在测试类中执行的。

此方法的另一个好处是跨测试的初始化代码的可重用性。

例如,你可以使用基于SpringJUnit4ClassRunner等记载here这样的:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations={"testContext.xml","services.xml"}) 
public class MyServiceTest { 

    @Autowired  
    private TestDataService testDataService; 

    @Before 
    public void setUp(){ 
     testDataService.addTestData(); 
    } 

    @Test 
    public void testSomething() throws Exception { 
     // ... 
    } 
} 


public interface TestDataService { 

    void addTestData(); 

} 

public class TestDataServiceImpl implements TestDataService { 

    @Transactional 
    public void addTestData(){ 
     // TODO 
    } 

} 

这就是我们做的东西在我们的基于Spring的项目。

确保transactional configuration是正确的。如果您想避免类/接口分离,请在元素中将proxy-target-class设置为true。

+0

感谢蒂姆,我喜欢你的答案,但我不能注入这样的初始化服务为我的测试对象(简单的DAO和不依赖于Hibernate会话工厂的bean工作得很好)。我觉得应用程序上下文启动不是标准的。任何想法可能会发生什么? – Francois 2010-05-27 16:04:26

+0

使用JUnit 4.5和Spring 3,我无法在我的测试类服务中注入@Transactional注释的服务。没有用@Transactional注释的服务可以注入很好。 – Francois 2010-05-27 18:11:29

+0

@Francois,他们根本没有被注射或他们抛出任何异常?还要哟使用接口/类分离?自动装配匹配类型,而不是名称。我需要更多信息来帮助你。 – 2010-05-27 18:50:45

1

dbUnit是一个很好的工作框架。

总之,它应该从setUp()方法开始,它会删除指定表中的所有内容,然后用XML文件中的内容填充它们。

其他你可以尝试在新的事务这样执行setUp()方法:

@Before 
@Transactional(propagation=Propagation.REQUIRES_NEW) 
public void setUp() { 
    // initial logic .. 
}