2012-08-03 67 views
10

我從未真正完成過單元測試,而且我在第一次測試中偶然發現並絆倒了。問題是_repository.Golfers.Count();總是表示DbSet爲空。單元測試使用模擬IDbSet的實體框架

我的測試很簡單,我只是想添加一個新的高爾夫球手

[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() 
     }; 
    } 

我已經建立了使用實體框架和代碼優先的數據模型。我嘲笑IDbSet一個派生類,以測試我的上下文(屈膝禮人在線,我記不太清了)

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 
} 

當調試和單步執行代碼,我可以看到我的實例_repository並用三個僞裝的高爾夫球手填充它,但是當我退出添加功能時,_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;''golffers'是一個私人領域('private IDbSet golfers;')。 – Sam 2013-07-08 06:49:44

回答

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,但我正在嘗試使用它。感謝您的鏈接。 – 2012-08-03 01:35:14