You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Ninject时,如何基于接口模拟Entity Framework上下文?

模拟ILikvidoWebsitesApiContext接口的方案

没问题!要模拟你的ILikvidoWebsitesApiContext接口用于测试,最常用也最顺手的工具是Moq(.NET生态里最流行的模拟框架)。下面我一步步给你拆解实现步骤:


1. 先准备好依赖包

首先确保你在测试项目里安装了Moq包:

  • 通过NuGet包管理器:Install-Package Moq
  • 或者用.NET CLI命令:dotnet add package Moq

如果想简化DbSet<T>的模拟工作,还可以安装Moq.EntityFrameworkCore辅助包,能省不少重复代码:

dotnet add package Moq.EntityFrameworkCore

2. 基础模拟步骤(不用辅助包)

假设你的ILikvidoWebsitesApiContext接口里包含DbSet<Product> Products { get; set; }这类集合属性,我们需要为每个DbSet模拟测试数据,再挂载到上下文接口的模拟实例上:

代码示例:

// 第一步:准备测试用的实体数据
var testProducts = new List<Product>
{
    new Product { Id = 1, Name = "测试商品1" },
    new Product { Id = 2, Name = "测试商品2" }
}.AsQueryable();

// 第二步:模拟DbSet<Product>
var mockProductsDbSet = new Mock<DbSet<Product>>();
// 让DbSet实现IQueryable的必要成员
mockProductsDbSet.As<IQueryable<Product>>().Setup(m => m.Provider).Returns(testProducts.Provider);
mockProductsDbSet.As<IQueryable<Product>>().Setup(m => m.Expression).Returns(testProducts.Expression);
mockProductsDbSet.As<IQueryable<Product>>().Setup(m => m.ElementType).Returns(testProducts.ElementType);
mockProductsDbSet.As<IQueryable<Product>>().Setup(m => m.GetEnumerator()).Returns(testProducts.GetEnumerator());

// 第三步:模拟你的上下文接口,把模拟好的DbSet挂载上去
var mockContext = new Mock<ILikvidoWebsitesApiContext>();
mockContext.Setup(c => c.Products).Returns(mockProductsDbSet.Object);

// 如果接口里还有其他DbSet(比如Orders),重复上面的步骤模拟即可

3. 简化版模拟(用Moq.EntityFrameworkCore)

有了辅助包,模拟DbSet会轻松很多,不用手动设置IQueryable的所有成员:

// 准备测试数据
var testProducts = new List<Product>
{
    new Product { Id = 1, Name = "测试商品1" },
    new Product { Id = 2, Name = "测试商品2" }
};

// 模拟上下文
var mockContext = new Mock<ILikvidoWebsitesApiContext>();
// 直接用ReturnsDbSet方法绑定测试数据
mockContext.Setup(c => c.Products).ReturnsDbSet(testProducts);

4. 在测试中使用模拟的上下文

把模拟好的上下文实例注入到你的服务里,就和生产环境中注入真实上下文一样:

// 创建服务实例,传入模拟的上下文
var productService = new ProductService(mockContext.Object);

// 调用服务方法并验证结果
var allProducts = productService.GetAllProducts();
Assert.Equal(2, allProducts.Count());

额外:验证上下文方法的调用

如果你的服务会调用上下文的SaveChanges()之类的方法,还可以模拟并验证它的调用情况:

// 先模拟SaveChanges方法,设置返回值
mockContext.Setup(c => c.SaveChanges()).Returns(1);

// 调用服务里的新增方法
productService.AddNewProduct(new Product { Name = "新商品" });

// 验证SaveChanges是否被调用了一次
mockContext.Verify(c => c.SaveChanges(), Times.Once);

内容的提问来源于stack exchange,提问作者Lars Holdgaard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:12:33