2013-04-03 22 views
11

私は現在、ユニットテストに私はEntity Frameworkを介して行わリポジトリをしようとしている:Entity Frameworkを使用するリポジトリパターンの単体テスト方法は?

私は起こるしたいどのようなことは、そのテストは、私はすべてのモックを使用せずにこれにしたい、実際には実際のデータベースへの接続/送信せずにリポジトリですフレームワーク。

現在、私のテストでは、データベースにデータを送信していますが、私が起こるたいこと/アドオンをテストし、それが唯一のテストのためなので、データベースに実際のデータを送信せずなどのメソッドを削除しています。ここで

は、リポジトリである:ここでは

namespace AbstractFactory.Repository 
{ 
    using System.Collections.Generic; 
    using System.Data.Entity; 
    using System.Linq; 

    /// <summary> 
    /// This class serves as the structure of the Author repository using a database 
    /// </summary> 
    public class DbAuthorRepository : IRepository<AuthorEntity> 
    { 

     private AbstractFactoryPatternEntities context; 

     public DbAuthorRepository(AbstractFactoryPatternEntities context) 
     { 
      this.context = context; 
     } 

     /// <summary> 
     /// Adds the specified author. 
     /// </summary> 
     /// <param name="author">The author.</param> 
     public void Add(AuthorEntity author) 
     { 
      context.AuthorEntities.Add(author); 
     } 

     /// <summary> 
     /// Removes the specified author. 
     /// </summary> 
     /// <param name="author">The author.</param> 
     public void Remove(AuthorEntity author) 
     { 
      this.context.AuthorEntities.Remove(author); 
     } 

     /// <summary> 
     /// Saves this instance. 
     /// </summary> 
     public void Save() 
     { 
      this.context.SaveChanges(); 
     } 

     /// <summary> 
     /// Gets all. 
     /// </summary> 
     /// <returns>returns a list of all the authors</returns> 
     public IEnumerable<AuthorEntity> GetAll() 
     { 
      List<AuthorEntity> result = this.context.AuthorEntities.Include(a => a.Books).ToList(); 

      return result; 
     } 

     /// <summary> 
     /// Gets the author by id. 
     /// </summary> 
     /// <param name="id">The id.</param> 
     /// <returns>returns an entity</returns> 
     public AuthorEntity GetById(int id) 
     { 
      AuthorEntity result = this.context.AuthorEntities.Single(a => a.AuthorId == id); 

      return result; 
     } 
    } 
} 

は、ユニットテストのための現在のコードです:

[TestMethod] 
     public void Add_MethodIsCalled_EntityCountIsIncrementedByOne() 
     { 
      using (ShimsContext.Create()) 
      { 
       ShimAbstractFactoryPatternEntities context = new ShimAbstractFactoryPatternEntities(new AbstractFactoryPatternEntities()); 
       DbAuthorRepository repository = new DbAuthorRepository(context); 
       repository.Add(new AuthorEntity { FirstName = "Test", LastName = "testing=" }); 
       var actual = repository.GetAll().Count(); 
       repository.Save(); 
       var expected = repository.GetAll().Count(); 
       Assert.AreNotEqual(actual, expected); 
      } 

      //AbstractFactoryPatternEntities context = new AbstractFactoryPatternEntities(); 
      //DbAuthorRepository repository = new DbAuthorRepository(context); 
      //var actual = repository.GetAll().Count(); 
      //repository.Add(new AuthorEntity { FirstName = "Testing", LastName = "MyTest" }); 
      //repository.Save(); 
      //var expected = repository.GetAll().Count(); 
      //Assert.AreNotEqual(actual, expected); 
     } 

     [TestMethod] 
     public void Remove_MethodIsCalled_EntityCountRemainsTheSame() 
     { 
      AbstractFactoryPatternEntities context = new AbstractFactoryPatternEntities(); 
      DbAuthorRepository repository = new DbAuthorRepository(context); 
      AuthorEntity newAuthor = new AuthorEntity { FirstName = "Testing", LastName = "MyTest" }; 
      repository.Add(newAuthor); 
      repository.Save(); 
      var actual = repository.GetAll().Count(); 
      Console.WriteLine(actual); 
      repository.Remove(newAuthor); 
      var expected = repository.GetAll().Count(); 
      Console.WriteLine(expected); 
      Assert.AreEqual(actual, expected); 
     } 

     [TestMethod] 
     public void Get_MethodIsCalled_CorrectAuthorIsRetrieved() 
     { 
      AbstractFactoryPatternEntities context = new AbstractFactoryPatternEntities(); 
      DbAuthorRepository repository = new DbAuthorRepository(context); 
      int target = 4; 
      AuthorEntity author = repository.GetById(target); 
      Assert.AreEqual(target, author.AuthorId); 
     } 

私はテストを行うために、シム/スタブ/偽物を使いたいです。

+0

何が質問ですか? –

+1

あなたのリポジトリが実行していることが、EFを呼び出す1行のコードであれば、単位テストの形式を全く行う必要はありません。 Bobさんも同意しています:http://blog.8thlight.com/uncle-bob/2013/03/06/ThePragmaticsOfTDD.html – IronMan84

+0

+ 1 to @ IronMan84 - フレームワークをテストするのは嫌いです。修正することはできません。私は起こるしたい何 –

答えて

14

Entity Frameworkリポジトリは、リポジトリインタフェースの具体的な実装です。具体的なので、データベースを抽象化してテストすることはできません。この具体的な実装のポイントは、データをデータベースに書き込むことです。

これは、EFリポジトリのテストでは、リポジトリが実際のデータベースに書き込むことを確認することを目的としています。テストの段階では、リポジトリメソッドを呼び出し、アサーションフェーズでは、データベースからデータを取得する(ado.netおそらく?)リポジトリがその仕事をしているかどうかをチェックする。

インメモリー・データ・ストアを使用するリポジトリーの別のインプリメンテーションを使用し、インメモリー・リポジトリーを他のサービスにインジェクトすると、物理データベースに書き込むことなくこれらのサービスをテストできます。他のサービスに注入されたリポジトリを模擬して、いくつかの動作テスト、つまりサービスがリポジトリを正しく使用しているかどうかをテストすることもできます。

+4

+1あまりにも多くの人が嘲笑されないものを模倣しようとします。私はいくつかの証拠を収集した[ここ](http://stackoverflow.com/a/13352779/861716)。 –

+0

@GertArnold:印象的な証拠。 –

+0

私が理解すれば、EFが動作することを確認するために、別のデータアクセス実装(ado.netを使用)を作成する必要があると言います。これは多くのオーバーヘッドを追加しませんか? – betitall

5

あなたは、このような努力として、インメモリDB、を使用してデータベースへの接続を置き換えることができます。次に、リポジトリロジックをテストすることができます。詳細はこちらをご覧くださいhere

+3

これはコメントでなければならないと思うし、それは答えではない。 –

関連する問題