Unit testing Entity Framework with Mock IDbSet(使用 Mock IDbSet 对实体框架进行单元测试)
问题描述
我以前从来没有真正做过单元测试,而且我在第一次测试时绊倒了.问题是 _repository.Golfers.Count(); 总是表明 DbSet 是空的.
I've never really done unit testing before, and I've stumbled and tripped on my first test. The problem is that the _repository.Golfers.Count(); always indicates that the DbSet is empty. 
我的测试很简单,我只是想添加一个新的高尔夫球手
My test is simple, I'm just trying to add a new golfer
[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 的派生类,以测试我的上下文(对网上的人行屈膝礼,我记不清了)
I've built a data model using Entity Framework and code-first. I've mocked an derived class for IDbSet in order to test my context (curtsy to people online that I can't remember exactly)
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 再次为空.我在这里想念什么?
When I debug and step through the code I can see that I instantiate the _repository and fill it with three faked golfers, but when I step out of the add function, the _respoistory.Golfers is empty again. when I add a new golfer, the _set.Add(entity) runs and the golfer is added, but again _respoistory.Golfers is empty. What am I missing here? 
更新
我很抱歉我是个白痴,但我没有在我的 MockGolfEntities 上下文中实现 set.我没有的原因是我之前尝试过,但不知道如何,继续前进,然后忘记了.那么,如何设置 IDbSet?这是我尝试过的,但它给了我一个堆栈溢出错误.感觉自己像个白痴,但是不知道怎么写set函数.
I'm sorry for being an idiot, but I hadn't implemented the set on my MockGolfEntities context. The reason I had not is that I tried before but couldn't figure out how, moved on, and forgot about it. So, how do I set an IDbSet?  This is what I've tried, but it gives me a Stack Overflow error. I feel like an idiot, but I can't figure out how to write the set function.
public class MockGolfEntities : DbContext, IContext
{
    public MockGolfEntities() {}
    public IDbSet<Golfer> Golfers { 
        get {
            return new InMemoryDbSet<Golfer>();
        }
        set {
            this.Golfers = this.Set<Golfer>();
        }
    }
}
推荐答案
您不需要实现 get/set,以下代码应该足以为您生成上下文.
You shouldn't need to implement the get/set, the following code should be enough to generate the context for you.
public class MockGolfEntities : DbContext, IContext
{
    public MockGolfEntities() {}
    public IDbSet<Golfer> Golfers { get; set;}
}
我已经实现了您在原始帖子中的代码,并且对我来说一切似乎都运行良好 - 您从哪里获得 InMemoryDbSet 的源代码?我正在使用 NuGet 包 1.3,也许你应该试试那个版本?
I've implemeted the code you had in your original post and everything seemed to work well for me - where did you get the source for the InMemoryDbSet? I'm using the NuGet package 1.3, maybe you should try that version?
这篇关于使用 Mock IDbSet 对实体框架进行单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:使用 Mock IDbSet 对实体框架进行单元测试
				
        
 
            
        - Web Api 中的 Swagger .netcore 3.1,使用 swagger UI 设置日期时间格式 2022-01-01
 - C#MongoDB使用Builders查找派生对象 2022-09-04
 - MoreLinq maxBy vs LINQ max + where 2022-01-01
 - 带有服务/守护程序应用程序的 Microsoft Graph CSharp SDK 和 OneDrive for Business - 配额方面返回 null 2022-01-01
 - 如何用自己压缩一个 IEnumerable 2022-01-01
 - C# 中多线程网络服务器的模式 2022-01-01
 - WebMatrix WebSecurity PasswordSalt 2022-01-01
 - 在哪里可以找到使用中的C#/XML文档注释的好例子? 2022-01-01
 - 输入按键事件处理程序 2022-01-01
 - 良好实践:如何重用 .csproj 和 .sln 文件来为 CI 创建 2022-01-01
 
						
						
						
						
						
				
				
				
				