2012-04-06 19 views
5

私はNoSQLデータベースを研究しており、ユニットテストに関する質問があります。ビジネスロジックを単体テストする適切な方法は何ですか? NoSQLデータベースをどうやって模擬しますか?NoSQL - 単体テスト用のデータベースを模擬する方法は?

+0

また、テスト用のメモリ内DBも考えられます。 –

+0

質問は何NoSQL技術です。多くの場合、メモリ内の機能を備えており、他には独自の仕掛けがあります。グラフDBは、RDBMSとは異なり、doc DBとは異なります。 – synhershko

+0

@synhershko - MongoDB – mtm927

答えて

2

ビジネスロジックはデータベースに直接アクセスするのではなく、データベースアクセスレイヤーを経由する必要があります。これにより、ユニットテストのために中間層をモックできます。これを行うには、依存関係注入とモックを使用できます。これらの両方を手助けできるフレームワークがありますが、手動で行うこともできます。ここでは例です:あなたが見ることができるように

public class DBDataProvider: IDataProvider 
{ 
    public string getData() 
    { 
     //SQL to get data from actual database. 
    } 
} 

が、これはあなたのビジネス層のためのデータを提供して何かのためのインタフェースを実装しています:

は、私たちがDALを持っていると言います。 、本番コードになりましたので

public BusinessClass 
{ 
    private IDataProvider dataProvider; 

    public BusinessClass() 
    { 
     dataProvider = new DBDataProvider(); 
    } 

    public BusinessClass(IDataProvider provider) 
    { 
     dataProvider = provider; 
    } 

    public void doBusinessStuff() 
    { 
     dataProvider.getData(); 
     //Do something with data. 
    } 

} 

、あなたはデフォルトのコンストラクタを使用して、あなたのビジネスクラスを行いますされます:あなたのビジネス層はこのようになります

public Interface IDataProvider 
{ 
    String getData(); 
} 

:それはこのようになります。 DBに接続してクラスを自動的に作成します。ただし、指定したIDataProviderを使用してBusinessClassを作成できることに注意してください。だから、あなただけのテストのために「偽」のデータプロバイダを行うことができます。

public class MockDataProvider: IDataProvider 
{ 
    public string getData() 
    { 
     //return some expected result that you can control, without doing a DB call. 
    } 
} 

は、今すぐあなたのテストでは、あなたは新しいMockDataProviderを作成することができ、かつBusinessClassのコンストラクタにそれを渡します。あなたのビジネスクラスは、実際のDBではなく、あなたのモックデータプロバイダを使用するようになりました。

ここで私は手ですべてを行いましたが、これがどのように機能するかのアイデアが得られます。実生活では、擬似および依存性注入フレームワークを使用して、そのコードをまとめて書くことができます。

+0

あなたはそうです。私はBLLの代わりにDALを意味しました。 – mtm927

+0

例で更新しました。 :) – Oleksi

+0

Oleski、 a)これは非常に悪い習慣と考えられます。 –

1

依存関係を模倣するのと同じ方法です。実装の詳細を抽象化してから、その契約を嘲笑していく素敵な、きちんとした契約を書いてください。通常、これはデータアクセスレイヤーを契約として使用して行います。
実際の実装の詳細がなくても、テストしたいメソッドのクエリがあるとしましょう(注意:ravenDBの例からこのコードをコピーしましたが、ravenDBについて0を知っているのでコンパイルできません)

あなたが別のクラスに出て、このロジックを分離した場合、それは、今8080でローカルホスト上のDBを必要とするため、/テストを模擬するためにかなり難しいことになるだろう
public void SomeMethod() 
{ 
    var name = "Hello"; 
    var motto = "World";      
    using (var docStore = new DocumentStore("localhost", 8080).Initialize()) 
    using (var session = documentStore.OpenSession()){ 
     session.Store(new Company { Name = name, Motto = motto });; 
     session.SaveChanges(); 
    } 
} 

public class AwesomeDAL 
    public virtual void AddCompany(string name, string motto){ 
     using (var docStore = new DocumentStore("localhost", 8080).Initialize()) 
     using (var session = documentStore.OpenSession()){ 
      session.Store(new Company { Name = name, Motto = motto });; 
      session.SaveChanges(); 
     } 
} 

と注入を可能に依存関係(AwesomeDal):

public class ClassBeingTested 
{ 
    public AwesomeDal DAL { get; set; } 
    public ClassBeingTested() : this(new AwesomeDal()){} 
    public ClassBeingTested(AwesomeDal dal) 
    { 
     this.DAL = dal; 
    } 

    public void SomeMethod() 
    { 
     var name = "Hello"; 
     var motto = "World";      
     this.DAL.AddCompany(name, motto); 
    } 
} 

これで、BLコードを単独でテストすることができます。または、データアクセスレイヤーが抽象化されており、その実装がMoqやRhinoMockのようなフレームワークで簡単にモック可能であるというデータベースの例外をシミュレートすることができます

+0

サンプルへのリンクがありますか?私は検索してみましたが、あまり見つけられませんでした。応答していただきありがとうございます。 – mtm927

+0

そうしないで、RavenDB.Embeddedを使用してInMemoryを実行してください - http://stackoverflow.com/questions/7533435/unit-testing-ravendbを参照してください。また、RavenDBでDAL/BLLレイヤーを使用しないでください。それはあまり意味がありません。 – synhershko

0

すでに投稿された(正しい)代替ソリューションを提案しましょう:実際の開発データベースを使用してください!実際のものより現実的なモックはありません。直接テストすると、コードが実際に実行されることがわかります。

データベースを簡単に抽象化することができれば、それを行うことをおすすめします。