C# 在asp.net中使用moq测试服务类
我有一个这样的服务类:C# 在asp.net中使用moq测试服务类,c#,asp.net,unit-testing,moq,xunit,C#,Asp.net,Unit Testing,Moq,Xunit,我有一个这样的服务类: public DbContextOptions<ShoppingCartContext> dummyOptions { get; } = new DbContextOptionsBuilder<ShoppingCartContext>().Options; [Fact] public async Task TestGetCategories() { //Arrange var dbContextMoq = new DbCont
public DbContextOptions<ShoppingCartContext> dummyOptions { get; } = new DbContextOptionsBuilder<ShoppingCartContext>().Options;
[Fact]
public async Task TestGetCategories()
{
//Arrange
var dbContextMoq = new DbContextMock<ShoppingCartContext>(dummyOptions);
//Create list of Categories
dbContextMoq.CreateDbSetMock(x => x.Categories, new[]
{
new Category { CategoryId = 1, CategoryName = "Items" },
new Category { CategoryId = 2, CategoryName = "Fruits" }
});
//Act
CategoryService service = new CategoryService(dbContextMoq.Object);
var result = await service.GetCategories();
//Assert
Assert.NotNull(result);
}
公共类CategoryService:ICategoryService
{
私有myContext_上下文;
公共类别服务(myContext上下文)
{
_上下文=上下文;
}
公共异步任务GetCategories()
{
返回(wait _context.Categories.toListSync())。选择(c=>newCategoryTo
{
CategoryId=c.CategoryId,
CategoryName=c.CategoryName
}).ToList();
}
}
我的上下文如下所示:
public DbContextOptions<ShoppingCartContext> dummyOptions { get; } = new DbContextOptionsBuilder<ShoppingCartContext>().Options;
[Fact]
public async Task TestGetCategories()
{
//Arrange
var dbContextMoq = new DbContextMock<ShoppingCartContext>(dummyOptions);
//Create list of Categories
dbContextMoq.CreateDbSetMock(x => x.Categories, new[]
{
new Category { CategoryId = 1, CategoryName = "Items" },
new Category { CategoryId = 2, CategoryName = "Fruits" }
});
//Act
CategoryService service = new CategoryService(dbContextMoq.Object);
var result = await service.GetCategories();
//Assert
Assert.NotNull(result);
}
公共数据库集类别{get;set;}
我对GetCategories()
的单元测试是:
[事实]
public void TestGetCategories()
{
//安排
Mock moq=新Mock();
var moqSet=new Mock();
moq.Setup(m=>m.Categories).Returns(moqSet.Object);
CategoryService服务=新的CategoryService(moq.Object);
//表演
var result=service.GetCategories();
//断言
Assert.NotNull(结果);
}
但是我的单元测试有错误。它说:
System.NotSupportedException:不支持的表达式:m=>m.Categories
有人能帮我修复安装部件吗?您不能将Moq用于不可覆盖的属性。它需要是抽象的或虚拟的,这就是为什么会出现错误 将
dbcontext
属性Categories
更改为virtual,然后重试
public virtual DbSet<Category> Categories {get;set;}
公共虚拟数据库集类别{get;set;}
另外,在模拟接口方法时不需要这样做,因为它们本质上是可重写的。我终于可以找到答案了。 正如@PeterCsala提到的,我们可以使用“EntityFrameworkCore3Mock” 你可以在这里找到它: 我的单元测试如下所示:
public DbContextOptions<ShoppingCartContext> dummyOptions { get; } = new DbContextOptionsBuilder<ShoppingCartContext>().Options;
[Fact]
public async Task TestGetCategories()
{
//Arrange
var dbContextMoq = new DbContextMock<ShoppingCartContext>(dummyOptions);
//Create list of Categories
dbContextMoq.CreateDbSetMock(x => x.Categories, new[]
{
new Category { CategoryId = 1, CategoryName = "Items" },
new Category { CategoryId = 2, CategoryName = "Fruits" }
});
//Act
CategoryService service = new CategoryService(dbContextMoq.Object);
var result = await service.GetCategories();
//Assert
Assert.NotNull(result);
}
public DbContextOptions dummyOptions{get;}=new DbContextOptions builder().Options;
[事实]
公共异步任务TestGetCategories()
{
//安排
var dbContextMoq=新的DbContextMock(dummyOptions);
//创建类别列表
dbContextMoq.CreateDbSetMock(x=>x.Categories,new[]
{
新类别{CategoryId=1,CategoryName=“Items”},
新类别{CategoryId=2,CategoryName=“Fruits”}
});
//表演
CategoryService服务=新的CategoryService(dbContextMoq.Object);
var result=await service.GetCategories();
//断言
Assert.NotNull(结果);
}
谢谢您的回答,但我收到另一个错误:“InvalidProxyConstructorArgumentsException:无法实例化类的代理”您得到的原因是Moq需要一个可访问的构造函数来创建模拟实例。如果没有无参数构造函数,则在创建模拟时需要提供构造函数参数。是否考虑使用以下nuget包之一来减轻EF模拟的痛苦:?作为先决条件,请将您的DbSet
属性设置为虚拟的。谢谢您的回答,我会试试。@PeterCsala非常感谢您的帮助。“EntityFrameworkCore3Mock”真的很有帮助。我很高兴它帮助了你。这归功于@huysentruitw。