2012-08-03 65 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