0

我们有一个基于 NSpring 1.2 和 NHibernate 2 的 Web 应用程序并使用 HibernateTemplate。Web 应用程序配置为使用OpenSessionInViewModule

然而,在我们的集成测试中,休眠会话被标记为InitDeferredClose,并且在大多数情况下,这对我们的测试来说很好。有一些服务功能在 Web 应用程序的上下文中运行良好,但在从测试工具调用时会失败。

例如:我有一个函数可以在事务中创建和更新多个对象。该函数标有 Transaction 属性,但测试失败并显示以下消息:

Illegal attempt to associate a collection with two open sessions

从 Web 应用程序调用时,事务成功完成

我应该如何配置 spring 和 hibernate 以便我的集成测试正确复制 Web 应用程序的功能?

4

2 回答 2

1

我已经重写了我的集成测试装置,以从Spring 测试框架提供的AbstractTransactionalDbProviderSpringContextTests类继承。

这确实在其自己的事务中运行每个测试,并在测试结束时(默认情况下)回滚。除了解决两个打开会话的问题外,我的测试运行得更快(无需每次都清除数据库)。

使用 spring 测试框架时要记住的重要一点是,必须确保应用程序代码的 spring 应用程序上下文和测试框架的上下文是一致的,否则外部事务和内部事务将是由两个不同的 Hibernate 会话工厂创建

于 2010-01-15T16:22:06.567 回答
1

您应该在测试的 SetUp 部分创建一个 SessionScope 实例,然后在最后(TearDown)关闭(处置)它。这应该很好地模仿 OSIV 模型。这是一个简化的示例:

using System;
using NHibernate;
using NUnit.Framework;
using Spring.Data.NHibernate.Support;

[TestFixture]
public class OsivKindOfTest
{
    private SessionScope scope;
    // get LocalSessionFactoryObject from somewhere
    // see Spring.Testing.NUnit and auto-injection
    private ISessionFactory sessionFactory;

    [SetUp]
    public void OnSetUp()
    {
        scope = new SessionScope(sessionFactory, null, true, FlushMode.Never, true);
    }

    public void TestSomething()
    {
        // just a dummy demo
        Console.WriteLine(sessionFactory.GetCurrentSession().Statistics.EntityCount);
    }

    [TearDown]
    public void TearDown()
    {
        if (scope != null)
        {
            scope.Dispose();
        }
    }
}

此示例期望 Spring 的 LocalSessionFactoryObject 将 ExposeTransactionAwareSessionFactory 设置为 true

于 2009-12-23T22:01:24.900 回答