2012-08-03 8 views
10

これまでに単体テストを行ったことはありませんでした。私は最初のテストで遭遇してトリップしました。問題は、_repository.Golfers.Count();が常にDbSetが空であることを示していることです。ユニットテストEntity Framework with Mock IDbSet

私のテストは、私はちょうど私がEntity Frameworkのコードと、最初に使用したデータモデルを構築した新しいゴルファー

[TestClass] 
public class GolferUnitTest //: GolferTestBase 
{ 
    public MockGolfEntities _repository; 

    [TestMethod] 
    public void ShouldAddNewGolferToRepository() 
    { 
     _repository = new MockGolfEntities(); 

     _repository.Golfers = new InMemoryDbSet<Golfer>(CreateFakeGolfers()); 

     int count = _repository.Golfers.Count(); 
     _repository.Golfers.Add(_newGolfer); 

     Assert.IsTrue(_repository.Golfers.Count() == count + 1); 
    } 

    private Golfer _newGolfer = new Golfer() 
    { 
     Index = 8, 
     Guid = System.Guid.NewGuid(), 
     FirstName = "Jonas", 
     LastName = "Persson" 
    }; 
    public static IEnumerable<Golfer> CreateFakeGolfers() 
    { 
     yield return new Golfer() 
     { 
      Index = 1, 
      FirstName = "Bill", 
      LastName = "Clinton", 
      Guid = System.Guid.NewGuid() 
     }; 
     yield return new Golfer() 
     { 
      Index = 2, 
      FirstName = "Lee", 
      LastName = "Westwood", 
      Guid = System.Guid.NewGuid() 
     }; 
     yield return new Golfer() 
     { 
      Index = 3, 
      FirstName = "Justin", 
      LastName = "Rose", 
      Guid = System.Guid.NewGuid() 
     }; 
    } 

を追加しようとしている、シンプルです。私はデバッグし、コードをステップ実行するとき、私は私がインスタンス化することを確認でき

public class InMemoryDbSet<T> : IDbSet<T> where T : class 
{ 
    readonly HashSet<T> _set; 
    readonly IQueryable<T> _queryableSet; 

    public InMemoryDbSet() : this(Enumerable.Empty<T>()) { } 

    public InMemoryDbSet(IEnumerable<T> entities) 
    { 
     _set = new HashSet<T>(); 

     foreach (var entity in entities) 
     { 
      _set.Add(entity); 
     } 

     _queryableSet = _set.AsQueryable(); 
    } 

    public T Add(T entity) 
    { 
     _set.Add(entity); 
     return entity; 

    } 

    public int Count(T entity) 
    { 
     return _set.Count(); 
    } 

    // bunch of other methods that I don't want to burden you with 
} 

(私は正確に覚えていないことを、オンラインで人々にカーテシを)私のコンテキストをテストするためにIDbSetの派生クラスを嘲笑しました _repositoryと3人の偽装ゴルファーで記入してください。しかし、私が追加機能から抜け出すと、 _respoistory.Golfersは再び空になります。新しいゴルファーを追加すると、 _set.Add(entity)が実行され、ゴルファーが追加されますが、 _respoistory.Golfersは空です。私はここで何が欠けていますか?

更新

私は馬鹿であることのために申し訳ありませんが、私は私のMockGolfEntities文脈にsetを実施していませんでした。私が以前に試したことはありましたが、どうやって動いて、忘れてしまったのか、それを忘れていないのです。では、IDbSetを設定するにはどうすればよいですか?これは私が試したことですが、それは私にスタックオーバーフローエラーを与えます。私は馬鹿のように感じますが、私は設定された機能を書く方法を理解することはできません。

public class MockGolfEntities : DbContext, IContext 
{ 
    public MockGolfEntities() {} 

    public IDbSet<Golfer> Golfers { 
     get { 
      return new InMemoryDbSet<Golfer>(); 
     } 
     set { 
      this.Golfers = this.Set<Golfer>(); 
     } 
    } 
} 
+0

'set'メソッドは、' this.Golfers'に代入して自分自身を呼び出しています。値はどこかに格納する必要があります。例: 'this.golfers = value;'ここで 'golfers'はプライベートフィールドです(' private IDbSet ゴルファー; ')。 – Sam

答えて

5

get/setを実装する必要はありません。次のコードでは、コンテキストを生成するのに十分なはずです。

public class MockGolfEntities : DbContext, IContext 
{ 
    public MockGolfEntities() {} 

    public IDbSet<Golfer> Golfers { get; set;} 

} 

私はあなたのオリジナルのポストに持っていたコードをimplemetedてきた、すべてが私のためにうまく動作するように見えた - どこInMemoryDbSetのソースを取得したのですか? NuGet package 1.3を使用しています。おそらくそのバージョンを試す必要がありますか?

+0

ありがとう - 私が望むなら、セットを実装する方法についてはまだ困惑していますが、私はIDbSetまで魔法を残して喜んでいます。私は無限ループでプロパティを設定しようとしているので、私のセットが狂っていることに気がついていましたが、私は絶望的でしたし、少なくとも私がショットをくれたことを示すいくつかのコードを投稿したかったのです。私はNuGetを使用しませんでしたが、私はそれを使用しようとしています。リンクありがとう。 –

関連する問題