简体   繁体   English

使用Mock IDbSet对实体框架进行单元测试

[英]Unit testing Entity Framework with Mock IDbSet

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(); 问题是_repository.Golfers.Count(); always indicates that the DbSet is empty. 始终表示DbSet为空。

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

I've built a data model using Entity Framework and code-first. 我使用Entity Framework和代码优先构建了一个数据模型。 I've mocked an derived class for IDbSet in order to test my context (curtsy to people online that I can't remember exactly) 我已经为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
}

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. 当我调试并逐步执行代码时,我可以看到我实例化_repository并用三个伪造的高尔夫球手填充它,但是当我退出添加功能时, _respoistory.Golfers再次为空。 when I add a new golfer, the _set.Add(entity) runs and the golfer is added, but again _respoistory.Golfers is empty. 当我添加一个新的高尔夫球手时,运行_set.Add(entity)并添加高尔夫球手,但是再次_respoistory.Golfers为空。 What am I missing here? 我在这里错过了什么?

Update 更新

I'm sorry for being an idiot, but I hadn't implemented the set on my MockGolfEntities context. 我很抱歉是个白痴,但我没有在我的MockGolfEntities上下文中实现该set 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 ? 那么,我该如何设置IDbSet This is what I've tried, but it gives me a Stack Overflow error. 这是我尝试过的,但它给了我一个Stack Overflow错误。 I feel like an idiot, but I can't figure out how to write the set function. 我觉得自己像个白痴,但我无法弄清楚如何编写set函数。

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

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

You shouldn't need to implement the get/set, the following code should be enough to generate the context for you. 您不需要实现get / set,以下代码应该足以为您生成上下文。

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

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

}

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? 我已经实现了原始帖子中的代码,一切似乎都适合我 - 你在哪里获得了InMemoryDbSet的源代码? I'm using the NuGet package 1.3 , maybe you should try that version? 我正在使用NuGet包1.3 ,也许你应该尝试那个版本?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM