0

我想使用Sqllite.InMemory功能來設置數據庫單元測試。 如果我運行一個單元測試,一切工作正常。如果我第二次運行相同的測試,我得到一個System.Data.SQLite.SQLiteException:沒有這樣的表:人奇怪的NHibernate Sqllite.InMemory行爲

等待一段時間和/或(?)重新啓動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

您已請求啓用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(); 

而且,由於從會話工廠產生的對話,這將是審慎處置之前,將所有會話會話工廠。

+0

更少有時更多:-)非常感謝! – core

+0

但是還有一個問題:因爲我不是在我的映射中添加程序集的地方知道NHibernate如何堅持我的域模型?當我嘗試'SessionContainer.Session.Save(person);'我得到了MappingException:沒有persister:.... Person。在沒有這樣的表格異常的情況下再次將配置路徑添加到配置結果中:-( – core

+0

我可能已經更清楚了,我的意思是這是我使用的Database()調用,我仍然有Mappings()和一些ExposeConfiguration( ),但沒有任何影響數據庫或連接到它的操作 –