惩戒EF的DbContext与起订量 [英] Mocking EF DbContext with Moq

查看:170
本文介绍了惩戒EF的DbContext与起订量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建我用嘲笑的DbContext服务单元测试。我创建了一个接口 IDbContext 具有以下功能:

 公共接口IDbContext :IDisposable的
{
IDbSet< T>设置< T>()其中T:类;
DbEntityEntry< T>进入< T>(T实体),其中T:类;
INT的SaveChanges();
}



我真正的背景下实现了这个接口 IDbContext 的DbContext



现在我试图嘲弄 IDbSet< ; T> 的背景下,因此它返回一个列表<使用者方式> 而不是

  [TestMethod的] 
公共无效TestGetAllUsers()
{
//安排
变种模拟=新的模拟< IDbContext>();
mock.Setup(X => x.Set<使用者>())
.Returns(新名单<使用者>
{
新用户{ID = 1}
});

UserService userService =新UserService(mock.Object);

//法案
VAR ALLUSERS = userService.GetAllUsers();

//断言
Assert.AreEqual(1,allUsers.Count());
}



我总是得到这个错误 .Returns

 
的最佳重载方法匹配'Moq.Language.IReturns< AuthAPI.Repositories .IDbContext,System.Data.Entity.IDbSet< AuthAPI.Models.Entities.User>> .Returns(System.Func< System.Data.Entity.IDbSet< AuthAPI.Models.Entities.User>>)
有一些无效参数


解决方案

我设法解决它通过创建一个 FakeDbSet< T> 类,它实现 IDbSet< T>

 公共类FakeDbSet< T> :IDbSet< T>其中T:类
{
&的ObservableCollection LT; T> _数据;
IQueryable的_query;

公共FakeDbSet()
{
_data =新的ObservableCollection< T>();
_query = _data.AsQueryable();
}

公共虚拟找不到(params对象[]键值)
{
抛出新NotImplementedException(从FakeDbSet<推导; T>并覆盖查找);
}

公众不要再增加(T项目)
{
_data.Add(项目);
回报率的项目;
}

公共t取出(T项目)
{
_data.Remove(项目);
回报率的项目;
}

公共牛逼连接(T项目)
{
_data.Add(项目);
回报率的项目;
}

公共牛逼分离(T项目)
{
_data.Remove(项目);
回报率的项目;
}

公共牛逼的Create()
{
返回Activator.CreateInstance< T>();
}

公共TDerivedEntity创建< TDerivedEntity>()其中TDerivedEntity:类,T
{
返回Activator.CreateInstance< TDerivedEntity>();
}

公众的ObservableCollection< T>当地
{
{返回_data; }
}

型IQueryable.ElementType
{
{返回_query.ElementType; }
}

System.Linq.Expressions.Expression IQueryable.Expression
{
{返回_query.Expression; }
}

IQueryProvider IQueryable.Provider
{
{返回_query.Provider; }
}

System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
返回_data.GetEnumerator();
}

&的IEnumerator LT; T> IEnumerable的< T> .GetEnumerator()
{
返回_data.GetEnumerator();
}
}

现在我的测试是这样的:

  [TestMethod的] 
公共无效TestGetAllUsers()
{
//安排
变种模拟=新的模拟< IDbContext>();
mock.Setup(X => x.Set<使用者>())
.Returns(新FakeDbSet<使用者>
{
新用户{ID = 1}
});

UserService userService =新UserService(mock.Object);

//法案
VAR ALLUSERS = userService.GetAllUsers();

//断言
Assert.AreEqual(1,allUsers.Count());
}


I'm trying to create a unit test for my service with a mocked DbContext. I created an interface IDbContext with the following functions:

public interface IDbContext : IDisposable
{
    IDbSet<T> Set<T>() where T : class;
    DbEntityEntry<T> Entry<T>(T entity) where T : class;
    int SaveChanges();
}

My real context implements this interface IDbContext and DbContext.

Now I'm trying to mock the IDbSet<T> in the context, so it returns a List<User> instead.

[TestMethod]
public void TestGetAllUsers()
{
    // Arrange
    var mock = new Mock<IDbContext>();
    mock.Setup(x => x.Set<User>())
        .Returns(new List<User>
        {
            new User { ID = 1 }
        });

    UserService userService = new UserService(mock.Object);

    // Act
    var allUsers = userService.GetAllUsers();

    // Assert
    Assert.AreEqual(1, allUsers.Count());
}

I always get this error on .Returns:

The best overloaded method match for
'Moq.Language.IReturns<AuthAPI.Repositories.IDbContext,System.Data.Entity.IDbSet<AuthAPI.Models.Entities.User>>.Returns(System.Func<System.Data.Entity.IDbSet<AuthAPI.Models.Entities.User>>)'
has some invalid arguments

解决方案

I managed to solve it by creating a FakeDbSet<T> class that implements IDbSet<T>

public class FakeDbSet<T> : IDbSet<T> where T : class
{
    ObservableCollection<T> _data;
    IQueryable _query;

    public FakeDbSet()
    {
        _data = new ObservableCollection<T>();
        _query = _data.AsQueryable();
    }

    public virtual T Find(params object[] keyValues)
    {
        throw new NotImplementedException("Derive from FakeDbSet<T> and override Find");
    }

    public T Add(T item)
    {
        _data.Add(item);
        return item;
    }

    public T Remove(T item)
    {
        _data.Remove(item);
        return item;
    }

    public T Attach(T item)
    {
        _data.Add(item);
        return item;
    }

    public T Detach(T item)
    {
        _data.Remove(item);
        return item;
    }

    public T Create()
    {
        return Activator.CreateInstance<T>();
    }

    public TDerivedEntity Create<TDerivedEntity>() where TDerivedEntity : class, T
    {
        return Activator.CreateInstance<TDerivedEntity>();
    }

    public ObservableCollection<T> Local
    {
        get { return _data; }
    }

    Type IQueryable.ElementType
    {
        get { return _query.ElementType; }
    }

    System.Linq.Expressions.Expression IQueryable.Expression
    {
        get { return _query.Expression; }
    }

    IQueryProvider IQueryable.Provider
    {
        get { return _query.Provider; }
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return _data.GetEnumerator();
    }

    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        return _data.GetEnumerator();
    }
}

Now my test looks like this:

[TestMethod]
public void TestGetAllUsers()
{
    //Arrange
    var mock = new Mock<IDbContext>();
    mock.Setup(x => x.Set<User>())
        .Returns(new FakeDbSet<User>
        {
            new User { ID = 1 }
        });

    UserService userService = new UserService(mock.Object);

    // Act
    var allUsers = userService.GetAllUsers();

    // Assert
    Assert.AreEqual(1, allUsers.Count());
}

这篇关于惩戒EF的DbContext与起订量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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