我有以下单元测试,需要使用
.ToListAsync
模拟 EF 扩展方法 moq
。由于 moq
无法模拟静态方法,并且扩展方法是静态方法,因此我不得不使用 mockableQuery.moq
库。但是仍然弹出System.NotSupportedException
抱怨扩展方法的使用。
我无法弄清楚我做错了什么。
using System.Reflection.Metadata;
using FluentAssertions;
using LanguageExt;
using LanguageExt.UnsafeValueAccess;
using Microsoft.EntityFrameworkCore;
using MockQueryable.Moq;
using Moq;
using xxx.Application.Features.Users.Queries.GetAllUserTypes;
using xxx.Application.Interfaces.Services;
using xxx.Domain.Entities;
namespace xxx.UnitTests.Application.Features.Users.Queries
{
public class GetAllUserTypesQueryUnitTests
{
[Fact]
public async Task Handler_Should_ReturnAllUserTypes()
{
// Arrange
List<AppUserType> userTypes =
[
new AppUserType { UserTypeId = 1, UserTypeName = "Type 1" },
new AppUserType { UserTypeId = 2, UserTypeName = "Type 2" }
];
Mock<DbSet<AppUserType>> mockSet = userTypes.AsQueryable().BuildMockDbSet();
mockSet
.Setup(m => m.ToListAsync(It.IsAny<CancellationToken>()))
.ReturnsAsync(userTypes);
Mock<IxxxDbContext> mockContext = new();
mockContext
.Setup(c => c.AppUserTypes)
.Returns(mockSet.Object);
GetAllUserTypesQueryHandler handler = new(mockContext.Object);
GetAllUserTypesQuery query = new();
// Act
Option<GetAllUserTypesResult> result = await handler.Handle(query, CancellationToken.None);
// Assert
_ = result.IsSome.Should().BeTrue();
_ = result.ValueUnsafe().UserTypes.Should().BeEquivalentTo(userTypes);
}
}
}
扩展方法不能被模拟有一个很好的理由,那就是它们不应该被模拟。它们对具体的事物进行操作,因此您需要嘲笑后者。如果您发现自己尝试模拟扩展方法,通常表明您做错了什么。
在您的情况下,
ToListAsync
和QueryableExtensions
的其他方法在IQueryable
上运行,这是您的数据源。 DbSet
是一个IQueryable
,你已经嘲笑过这个了。删除您尝试模拟该方法的代码,您的测试应该会通过。