单元测试实体框架与模拟IDbSet [英] Unit testing Entity Framework with Mock IDbSet

查看:299
本文介绍了单元测试实体框架与模拟IDbSet的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从来没有真正做过单元测试之前,我已经迷迷糊糊地绊倒在我的第一次测试。问题是,在 _repository.Golfers.Count(); 总是指示 DbSet 是空的。

我的测试很简单,我只是想添加一个新的高尔夫球手

  [识别TestClass]
公共类GolferUnitTest //:GolferTestBase
{
    公共MockGolfEntities _repository;    [测试方法]
    公共无效ShouldAddNewGolferToRepository()
    {
        _repository =新MockGolfEntities();        _repository.Golfers =新InMemoryDbSet&所述;高尔夫球>(CreateFakeGolfers());        诠释计数= _repository.Golfers.Count();
        _repository.Golfers.Add(_newGolfer);        Assert.IsTrue(_repository.Golfers.Count()==计数+ 1);
    }    私人高尔夫球_newGolfer =新高尔夫()
    {
        索引= 8,
        GUID = System.Guid.NewGuid(),
        名字=乔纳斯
        姓氏=佩尔松
    };
    公共静态的IEnumerable<高尔夫球员GT; CreateFakeGolfers()
    {
        产量返回新高尔夫()
        {
            索引= 1,
            名字=条例,
            姓氏=克林顿,
            GUID = System.Guid.NewGuid()
        };
        产量返回新高尔夫()
        {
            索引= 2,
            名字=李,
            姓氏=维斯特伍德
            GUID = System.Guid.NewGuid()
        };
        产量返回新高尔夫()
        {
            索引= 3,
            名字=贾斯汀,
            姓氏=玫瑰,
            GUID = System.Guid.NewGuid()
        };
    }

我已经建立了使用实体框架和code-第一个数据模型。我嘲笑IDbSet一个派生类中,以(网上行屈膝礼的人,我记不太清了)测试我的上下文

 公共类InMemoryDbSet< T> :IDbSet< T>其中T:类
{
    只读的HashSet< T> _组;
    只读的IQueryable< T> _queryableSet;    公共InMemoryDbSet():这个(Enumerable.Empty< T>()){}    公共InMemoryDbSet(IEnumerable的< T>实体)
    {
        _set =新的HashSet< T>();        的foreach(在实体VAR实体)
        {
            _set.Add(实体);
        }        _queryableSet = _set.AsQueryable();
    }    市民不要再增加(T实体)
    {
        _set.Add(实体);
        返回实体;    }    公众诠释计数(T实体)
    {
        返回_set.Count();
    }    //其他方法一堆,我不想给你添麻烦
}

当我调试,并逐步完成了code我可以看到我实例化 _repository 并用三个填充伪造的球手,但是当我走出的添加功能, _respoistory.Golfers 又是空的。当我添加一个新的球员,在 _set.Add(实体)运行和高尔夫球手被添加,但同样 _respoistory.Golfers 是空的。我缺少的是在这里吗?

更新

我是一个傻瓜抱歉,但我没有执行设置我的 MockGolfEntities 背景。我没有的原因是,我尝试过,但无法弄清楚如何,感动,并忘了。所以,我怎么设置 IDbSet ?这是我尝试过,但它给了我一个堆栈溢出错误。我觉得自己像个白痴,但我无法弄清楚如何写设置功能。<​​/ P>

 公共类MockGolfEntities:的DbContext,IContext
{
    公共MockGolfEntities(){}    公共IDbSet&LT;高尔夫球员GT;高尔夫球手{
        获得{
            返回新InMemoryDbSet&LT;高尔夫球员GT;();
        }
        集合{
            this.Golfers = this.Set&LT;高尔夫球员GT;();
        }
    }
}


解决方案

您不应该需要实现的get / set,下面code应该足以产生的背景为您服务。

 公共类MockGolfEntities:的DbContext,IContext
{
    公共MockGolfEntities(){}    公共IDbSet&LT;高尔夫球员GT;高尔夫球手{搞定;组;}}

我Implemeted一个在code你在原来的职位了,一切都似乎很适合我的工作 - 从哪里弄来的InMemoryDbSet源?我使用的是的NuGet包1.3 ,也许你应该尝试的版本?

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

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
}

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?

Update

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

解决方案

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

}

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?

这篇关于单元测试实体框架与模拟IDbSet的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆