2010-03-17 167 views
2

我想單元測試一個DEPENDENT服務層,它允許我在不使用NUnit模擬的情況下執行CRUD操作。我知道這可能是不好的做法,但無論如何我都想嘗試一下 - 即使測試需要運行一整夜。我的數據是使用NHibernate持久化的,我已經實現了一個「引導」數據庫的小型庫,我可以在[Setup]方法中使用它。我只是想知道是否有人做了類似的事情,以及引導數據庫的最快方法是什麼。我使用的是這樣的:單元測試服務層 - NUnit,NHibernate

var cfg = new Configuration(); 
      cfg.Configure(); 
      cfg.AddAssembly("Bla"); 
      new SchemaExport(cfg).Execute(false, true, false); 

建立數據庫模式。之後,我從一些Excel表中填充一些查找表。

任何反饋將非常感激。謝謝。

基督教

+2

外部資源?那些不再是單元測試你正在嘗試實現,但集成測試。 – 2010-03-17 09:47:08

+0

好的,我知道。讓我們叫它測試然後( - : – cs0815 2010-03-17 10:01:09

回答

2

Ayende在此blog post中有一個很好的示例。他的例子如下所示,我的評論。

由於配置創建起來很昂貴,因此每次測試運行時只創建一次。使用SQLite內存數據庫是因爲這是執行查詢的最快方式。

public class InMemoryDatabaseTest : IDisposable 
{ 
    private static Configuration Configuration; 
    private static ISessionFactory SessionFactory; 
    protected ISession session; 

    public InMemoryDatabaseTest(Assembly assemblyContainingMapping) 
    { 
     if (Configuration == null) 
     { 
      Configuration = new Configuration() 
       .SetProperty(Environment.ReleaseConnections,"on_close") 
       .SetProperty(Environment.Dialect, typeof (SQLiteDialect).AssemblyQualifiedName) 
       .SetProperty(Environment.ConnectionDriver, typeof(SQLite20Driver).AssemblyQualifiedName) 
       .SetProperty(Environment.ConnectionString, "data source=:memory:") 
       .SetProperty(Environment.ProxyFactoryFactoryClass, typeof (ProxyFactoryFactory).AssemblyQualifiedName) 
       .AddAssembly(assemblyContainingMapping); 

      SessionFactory = Configuration.BuildSessionFactory(); 
     } 

     session = SessionFactory.OpenSession(); 

     new SchemaExport(Configuration).Execute(true, true, false, true, session.Connection, Console.Out); 
    } 

    public void Dispose() 
    { 
     session.Dispose(); 
    } 
} 

當使用這個,每個測試開始創建所需的數據。

public class BlogTestFixture : InMemoryDatabaseTest 
{ 
    public BlogTestFixture() : base(typeof(Blog).Assembly) 
    { 
    } 

    [Fact] 
    public void CanSaveAndLoadBlog() 
    { 
     object id; 

     using (var tx = session.BeginTransaction()) 
     { 
      id = session.Save(new Blog 
      { 
       AllowsComments = true, 
       CreatedAt = new DateTime(2000,1,1), 
       Subtitle = "Hello", 
       Title = "World", 
      }); 

      tx.Commit(); 
     } 

     session.Clear(); 


     using (var tx = session.BeginTransaction()) 
     { 
      var blog = session.Get<Blog>(id); 

      Assert.Equal(new DateTime(2000, 1, 1), blog.CreatedAt); 
      Assert.Equal("Hello", blog.Subtitle); 
      Assert.Equal("World", blog.Title); 
      Assert.True(blog.AllowsComments); 

      tx.Commit(); 
     } 
    } 
} 
2

當寫這樣集成測試,最重要的事情要記住,你還是應該

  • 自動化儘可能地(最好是所有),其中包括設置建立數據庫並在使用後再次刪除
  • 避免General Fixture反模式,這意味着每個測試用例都應該以空數據庫開始,而我用Back Door Manipulation填寫適當的行。

我在過去幾次寫了大約my own experiences with testing against databases

+0

謝謝,我會看看這個。 – cs0815 2010-03-17 10:41:20