我遵循这个文档
我正在尝试构建一个测试项目,以便能够模拟DbContext和服务。
我DbContext:
public class ProjectDbContext : DbContext
{
public DbSet<Item> Items { get; set; }
public ProjectDbContext(DbContextOptions<ProjectDbContext> opt) : base(opt)
{}
}
ISerializable:
public interface ISerializable
{
Task<bool> SaveChangesAsync();
bool SaveChanges();
}
基础服务:
public class BaseService : ISerializable
{
protected readonly ProjectDbContext context;
public BaseService(ProjectDbContext context)
{
context = context;
}
public async Task<bool> SaveChangesAsync()
{
var result = await context.SaveChangesAsync();
return result >= 0;
}
public bool SaveChanges()
{
var result = context.SaveChanges();
return result >= 0;
}
}
My Interface for Items Service:
public interface IItemsService : ISerializable
{
Item GetById(Guid id);
}
项目服务:
public class ItemsService : BaseService, IItemsService
{
public ItemsService(ProjectDbContext context)
: base(context)
{ }
public Item GetById(Guid id)
{
return context.Items.FirstOrDefault(x => x.Id == id);
}
}
我的测试:
public class ItemTest
{
private readonly Mock<DbSet<Item>> _mockSet = new Mock<DbSet<Item>>();
private Mock<ProjectDbContext> _mockContext;
public ItemTest()
{
_mockContext = new Mock<ProjectDbContext >();
_mockContext.Setup(m => m.Items).Returns(_mockSet.Object);
}
[Fact]
public void GetById_ShouldReturnItemWhenItemExists()
{
// Service
var repository = new ItemsService(_mockContext.Object);
// Arrange
var itemId = Guid.NewGuid();
// Act
var item = repository.GetById(itemId, CancellationToken.None);
// Assert
Assert.Equal(itemId, item.Id);
}
}
错误信息:
系统。NotSupportedException不支持的表达式:m =>m.Items不可重写的成员(这里:ProjectDbContext.get_Items)不能在设置/验证表达式中使用。在Moq.Guard。IsOverridable(MethodInfo方法,Expression表达式)在C:projectsmoq4srcMoqGuard.cs:第99行在Moq.InvocationShape . .C:projectsmoq4srcMoqInvocationShape.cs:第84行。(LambdaExpression表达式,MethodInfo方法,IReadOnlyList'1参数,Boolean exactGenericTypeArguments, Boolean skipMatcherInitialization, Boolean allowNonOverridable在Moq.ExpressionExtensions。__split |5_0(表达式e,表达式&r, InvocationShape&p,布尔赋值,布尔allowNonOverridableLastProperty)在C:projectsmoq4srcMoqExpressionExtensions.cs:行324在Moq.ExpressionExtensions。分割(LambdaExpression表达式,布尔allowNonOverridableLastProperty)在C:projectsmoq4srcMoqExpressionExtensions.cs:第149行在Moq.Mock。SetupRecursive[TSetup](模拟模拟,LambdaExpression表达式,Func'4 setupLast, Boolean allowNonOverridableLastProperty)在C:projectsmoq4srcMoqMock.cs:第601行在Moq.Mock。设置(模拟模拟,LambdaExpression表达式,条件条件)在C:projectsmoq4srcMoqMock.cs: 505行在Moq.Mock 1。设置[结果](表达式'1表达式)在C:projectsmoq4srcMoqMock '1 .cs:行454在ItemTest.ctor () ............ ItemTest.cs:第20行
错误显示以下行不可重写:
_mockContext.Setup(m => m.Items).Returns(_mockSet.Object);
我试图使项目DbSet
成为virtual
成员。然后我开始得到:
Castle.DynamicProxy.InvalidProxyConstructorArgumentsException无法实例化类的代理:....ProjectDbContext.
添加无参数构造函数会抛出另一个异常,这让我认为我做错了什么。如果你能帮助我解决这个问题,我将不胜感激。
添加一个无参数构造函数对我来说是有效的,但是然后你需要添加一个新的'设置行',在那里你得到一个模拟你的'Items':
public DbSet<Item> GetItems() {
//your logic
}
并添加
_mockSet.Setup(i => i).Returns(GetItems());
到你的测试构造函数