奇怪的NHibernate Sqlite.In内存行为

时间:2012-12-20 10:56:36

标签: unit-testing nhibernate fluent-nhibernate visual-studio-2012

我正在尝试使用Sqllite.InMemory功能设置数据库单元测试。 如果我进行单元测试,一切正常。如果我第二次运行相同的测试,我得到一个System.Data.SQLite.SQLiteException:没有这样的表:Person

等待一段时间和/或(?)重新启动Visual Studio后,我可以再次运行单元测试。

配置或会话处理有问题吗?

public abstract class InMemoryDatabaseFixture : IDisposable
{
    private const string ConnectionString
        = "Data Source=:memory:;Version=3;New=True;Pooling=True;Max Pool Size=1;";

    private readonly ISessionFactory _sessionFactory;
    private readonly ISession _session;

    protected InMemoryDatabaseFixture()
    {
        var config = SQLiteConfiguration.Standard.InMemory().ShowSql().ConnectionString(ConnectionString);
        _sessionFactory = Fluently.Configure()
            .Database(config)
            .Mappings(m => m.FluentMappings.AddFromAssemblyOf<SessionContainer>())
            .ExposeConfiguration(cfg => new SchemaUpdate(cfg).Execute(true, true))
            .BuildSessionFactory();

        _session = _sessionFactory.OpenSession();

        SessionContainer = MockRepository.GenerateMock<ISessionContainer>();
        SessionContainer.Stub(sc => sc.SessionFactory).Return(_sessionFactory);
        SessionContainer.Stub(sc => sc.Session).Return(_session);
    }

    protected ISessionContainer SessionContainer { get; private set; }

    public void Dispose()
    {
        _sessionFactory.Dispose();
        _session.Dispose();
    }
}

这里简单介绍一下基类:

[TestFixture]
public class FinderFixture : InMemoryDatabaseFixture
{
    [Test]
    public void Test()
    {
        var finder = new Finder(SessionContainer);

        var result = finder.Find();

        Assert.That(result, Is.Not.Null);
    }
}

更新:经过一些试验后,最终我的工作配置。在构建SessionFactory之后导出模式正在发挥作用。

Configuration configuration = null;
_sessionFactory = Fluently.Configure()
    .Database(SQLiteConfiguration.Standard.InMemory().ShowSql())
    .ExposeConfiguration(cfg => configuration = cfg)
    .Mappings(m => m.FluentMappings.AddFromAssemblyOf<SessionContainer>())
    .BuildSessionFactory();

_session = _sessionFactory.OpenSession();
var export = new SchemaExport(configuration);
export.Execute(true, true, false, _session.Connection, null);

1 个答案:

答案 0 :(得分:1)

您已请求启用ADO.NET提供程序中的连接池。即使在NHibernate关闭它之后,这也会使底层连接保持活动状态。

在我自己的单元测试中,我只是(基于您的原始代码):

_sessionFactory = Fluently.Configure()
        .Database(SQLiteConfiguration.Standard.InMemory())
        .Mappings(m => m.FluentMappings.AddFromAssemblyOf<SessionContainer>())
        .ExposeConfiguration(cfg => new SchemaUpdate(cfg).Execute(true, true))
        .BuildSessionFactory();

此外,由于会话是从会话工厂生成的,因此在处理会话工厂之前处理所有会话是明智的。