2011-06-21 5 views
0

Fluent NHibernate DatabaseのIn Memory SQLite Unitテストをいくつか設定しました。それはうまく動作します。Fluent nHibernateによるユニットテスト - 各テストの可能性のためのデータの削除

namespace Testing.Database { 
    /// <summary> 
    /// Represents a memory only database that does not persist beyond the immediate 
    /// testing usage, using <see cref="System.Data.SQLite"/>. 
    /// </summary> 
    public abstract class InMemoryDatabase : IDisposable { 
     /// <summary> 
     /// The configuration of the memorized database. 
     /// </summary> 
     private static Configuration Configuration { get; set; } 

     /// <summary> 
     /// The singleton session factory. 
     /// </summary> 
     protected static ISessionFactory SessionFactory { get; set; } 

     /// <summary> 
     /// The current session being used. 
     /// </summary> 
     protected ISession Session { get; set; } 

     protected InMemoryDatabase() { 
      SessionFactory = CreateSessionFactory(); 
      Session = SessionFactory.OpenSession(); 
      BuildSchema(Session); 
     } 

     /// <summary> 
     /// Construct a memory based session factory. 
     /// </summary> 
     /// <returns> 
     /// The session factory in an SQLite Memory Database. 
     /// </returns> 
     private static ISessionFactory CreateSessionFactory() { 
      return FluentNHibernate.Cfg.Fluently.Configure() 
      .Database(FluentNHibernate.Cfg.Db.SQLiteConfiguration 
       .Standard 
       .InMemory() 
       .ShowSql()) 
      .Mappings(mappings => mappings.FluentMappings.AddFromAssemblyOf<Data.Mappings.AspectMap>()) 
      .ExposeConfiguration(configuration => Configuration = configuration) 
      .BuildSessionFactory(); 
     } 

     /// <summary> 
     /// Builds the NHibernate Schema so that it can be mapped to the SessionFactory. 
     /// </summary> 
     /// <param name="Session"> 
     /// The <see cref="NHibernate.ISession"/> to build a schema into. 
     /// </param> 
     private static void BuildSchema(ISession Session) { 
      var export = new NHibernate.Tool.hbm2ddl.SchemaExport(Configuration); 
      export.Execute(true, true, false, Session.Connection, null); 
     } 

     /// <summary> 
     /// Dispose of the session and released resources. 
     /// </summary> 
     public void Dispose() { 
      Session.Dispose(); 
     } 
    } 
} 

NUnitを使用すること)だから今、それを使用するためには、私はちょうどInMemoryDatabaseを継承し、このように私の試験方法を、追加します。

[TestFixture] 
    public class PersistenceTests : InMemoryDatabase { 
     [Test] 
     public void Save_Member() { 
      var member = // ...; 
      Session.Save(member); // not really how it looks, but you get the idea... 
     } 
    } 

これは問題ではありません。します。しかし、同じクラスの2つのテストで同様のデータをテストすると、たとえば...

Username_Is_Unique()そして次にEmail_Is_Unique()です。実際のテストではありませんが、良い例です。

[Test] 
public void Username_Is_Unique(){ 
    var user = new User { 
     Name = "uniqueName" 
     Email = "uniqueEmail" 
    }; 

    // do some testing here... 
} 
[Test] 
public void Email_Is_Unique(){ 
    var user = new User { 
     Name = "uniqueName" 
     Email = "uniqueEmail" 
    }; 

    // do some testing here... 
} 

私はこれらが非常に悪いテストであることを認識しています。これらは実際のテストではありません。私は例を引用しています。

どちらの場合でも、私はUserまたはMemberのモックを作成してデータベースに送信します。

最初のものはうまく動作しますが、データベースはメモリに格納されています(これは私が言いましたので意味があります)、2番目のものはありません。事実、単体テストは単体テストのため、実世界の状況を反映しません。しかし、それらを連続して一括して実行すると、現実の世界のように振る舞います。(部分的に良いことだと思います)

それぞれの方法の後にメモリデータベースをフラッシュします。だから私はコンストラクタを繰り返すことでこれを行う簡単な方法を思いついた。これはInMemoryDatabaseクラスにあります。私は私のテストを行う前に、

protected void Restart() { 
      SessionFactory = CreateSessionFactory(); 
      Session = SessionFactory.OpenSession(); 
      BuildSchema(Session); 
     } 

はだから今、私の継承クラスの各メソッドでは、私がRestart()を呼びます。

私はこれが私の問題を解決するための意図された、または効率的な方法ではないと感じます。誰かがより良いソリューションを提案できますか?

関連性がある場合は、永続性のためにFluent nHibernate、私のMockingの場合はTelerik JustMockを使用していますが、私のデータベースのものでは、まだ模擬が必要です。

答えて

1

すべてのテストでデータベースを削除して再作成する必要があります。すべてのテストは、他のテストとは独立している必要があります。あなたは、データベースのusingステートメントに各テストをラップすることができ、また

最初のテストは、セットアップの方法を使用してい(ここではNUnitのを仮定したが他の人が同じ機能を持っている)、2ことを行う
[SetUp] 
    public void Setup() 
    { 
     // Create in memory database 
     Memdb = new InMemoryDatabase(); 
    } 

を行うことができます。例えば、

[Test] 
public void Test() 
{ 
    using(var db = new InMemmoryDatabase()) 
    { 
     Do Some Testing Here 
    } 
}