【问题标题】:Spring and JUnit annotated tests: creating fixtures in separate transactionsSpring 和 JUnit 注释测试:在单独的事务中创建夹具
【发布时间】:2011-02-24 06:38:25
【问题描述】:

我正在使用 Spring 和 JUnit 测试我的 Hibernate DAO。

我希望每个测试方法都以预先填充的数据库开始,即 Java 对象已保存在数据库中,在已提交的 Hibernate 事务中。我该怎么做?

使用@After 和@Before,方法在与@Test 和@Transactional 修饰的方法相同的Hibernate 事务中执行(在真正的测试方法开始时第一级缓存可能不会被刷新)。 @BeforeTransaction 和 @AfterTransaction 显然不能与 Hibernate 一起使用,因为即使该方法除了 @Before/AfterTransaction 之外还使用 @Transactional 注释,它们也不会创建事务。

有什么建议吗?

【问题讨论】:

    标签: hibernate spring junit annotations


    【解决方案1】:

    一种方法是使用事务方法将初始化逻辑外部化到外部服务,这些事务方法从测试类中的 @BeforeTransaction 和 @AfterTransaction 注释方法执行。

    这种方法的另一个好处是初始化代码在测试之间的可重用性。

    例如,您可以像这样使用 here 描述的 SpringJunit4ClassRunner:

    @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。

    【讨论】:

    • 谢谢 Timo,我喜欢你的回答,但我无法将这样的初始化服务注入到我的测试对象中(虽然简单的 DAO 和不依赖于 Hibernate 会话工厂的 bean 工作得很好)。我的印象是应用程序上下文启动不是标准的。知道会发生什么吗?
    • 使用 JUnit 4.5 和 Spring 3,我无法在我的测试类中注入带有 @Transactional 注释的服务。不过,未使用 @Transactional 注释的服务可以很好地注入。
    • @Francois,他们只是没有被注入还是抛出任何异常?你也使用接口/类分离吗? Autowired 按类型匹配,而不是按名称匹配。我需要更多信息来帮助你。
    • 谢谢蒂莫。他们只是没有被注入还是抛出任何异常?它们在注入时抛出异常。如果我从应用程序上下文中列出 bean,它们就在这里,但转换它们失败。如果我删除所有 @Transaction 注释,它就可以工作。你也使用接口/类分离吗? TestSetup 服务系列完全独立于测试类。 TestService 系列遵循简单的单例/按类型自动装配的范例。
    • 好吧,我的猜测是 Spring AOP 代理出了点问题,我发布了一个应该可以工作的示例。
    【解决方案2】:

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

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

    否则,您可以尝试在新事务中执行setUp() 方法,如下所示:

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

    【讨论】:

      猜你喜欢
      • 2016-04-21
      • 1970-01-01
      • 2021-01-06
      • 2012-09-15
      • 2017-10-30
      • 1970-01-01
      • 2021-08-16
      • 2011-06-10
      • 2016-01-11
      相关资源
      最近更新 更多