当前位置: 首页 > 知识库问答 >
问题:

用Moq模拟EF DbContext

太叔高义
2023-03-14

我试图用模拟的dbcontext为我的服务创建一个单元测试。我创建了一个接口idbcontext,具有以下函数:

public interface IDbContext : IDisposable
{
    IDbSet<T> Set<T>() where T : class;
    DbEntityEntry<T> Entry<T>(T entity) where T : class;
    int SaveChanges();
}
[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());
}
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

共有1个答案

井旺
2023-03-14

我通过创建一个实现idbset fakedbset 类来解决这个问题

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

现在我的测试如下所示:

[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());
}
 类似资料:
  • 如果我错了请纠正我,但看起来Moq只能模拟一个公共类,它有一个公共的无参数构造函数,要模拟的方法是。我并不想让这些类公开可见。我是不是错过了一些与Moq的东西,或者只是不适合我想做的事情? 我想我可以创建一个ClassB实现的接口(例如“ICLASSB”),将其注入ClassA,并模拟该接口。ClassB仍然可以是内部的(尽管我意识到接口方法必须是公共的)。虽然这可以工作,但我对创建大量接口感到不

  • 使用。NET核心IoC容器注入工厂,该方法所做的是从工厂创建一个新客户机: 然后使用客户机从REST服务获取数据:

  • moq

    一个流行、友好的 .NET 模拟库 Moq(发音为“Mock you”或“Mock”)是.NET中唯一一个完全利用 .NET Linq 表达式树和 lambda 表达式而从头开发的模拟库,这使它成为最高效、类型安全和重构友好的模拟库。它支持模拟接口和类。它的API非常简单和直接,不需要任何关于模拟概念的知识或经验。 示例代码: var mock = new Mock<ILoveThisFramew

  • 我试图在测试中模拟一个调用,但我得到了一个错误,因为它调用了真正的方法,而不是模拟它。 这是我的方法 } 这是我的测试课 测试实际上调用了受保护的方法config Setter,并在设置代理时失败。帮助我理解我在这里做错了什么。

  • 问题内容: 我对模拟还很陌生,并且我一直在尝试模拟实际内容(本质上仅在内存中创建一个虚拟文件),以便在任何时候都不会将任何数据写入磁盘。 我尝试过模拟文件和模拟尽可能多的属性的解决方案,然后还使用文件写入器/缓冲写入器将其写入,但是这些方法不能很好地工作,因为它们需要规范路径。有人找到了除此以外的解决方案,但我正在解决这个错误? 我一直在这样做: 任何想法或指导都将非常有帮助。在此之后的某个地方,

  • 出于学校目的,我正在创建一个使用股票API的应用程序。 我正在尝试为一种获取过去10年所有股票数据的方法编写一个测试。我不想实际获取所有这些数据,而是想抛出一个异常。 我想测试的方法: 股票时间系列(....)调用可以抛出阿尔法仓位异常。 我这样嘲弄了TimeSeries类: 在我的测试类中,我想模拟这个调用,并返回一个异常而不是实际数据。 无论我多么试图嘲笑这段代码,它永远不会抛出异常。它将始终