我正在使用。net 6,我试图模拟IQueryable返回来实现IAsyncQueryProvider使用MockQueryable库,但我面临着同样的错误,没有库:
信息:系统。InvalidOperationException:源'IQueryable'的提供程序没有实现'IAsyncQueryProvider'。只有实现了'IAsyncQueryProvider'的提供程序才能用于实体框架的异步操作。
也许有人能帮我指出一些可能是一个明显的错误?这是我的单元测试类:堆栈跟踪:EntityFrameworkQueryableExtensions。ExecuteAsync[TSource, result](MethodInfo operatorMethodInfo, IQueryable
1 source, Expression expression, CancellationToken cancellationToken) EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable
1 source, CancellationToken CancellationToken)EntityFrameworkQueryableExtensions。FirstOrDefaultAsync[TSource](IQueryable ' 1 source, CancellationToken CancellationToken)UserService。gettexistinguser (String externalId, CancellationToken CancellationToken)行81UserService。创建同步(UserDto dto, CancellationToken CancellationToken)第21行UserServiceTests.CreateAsync_ShouldCreateUser_WhenUserDoesNotExist()第46行——前一个位置的堆栈跟踪结束——
public class UserServiceTests
{
private readonly UserService _sut;
private readonly Mock<IRepository<User>> _userRepositoryMock = new();
public UserServiceTests()
{
_sut = new UserService(_userRepositoryMock.Object);
}
[Fact]
public async Task CreateAsync_ShouldCreateUser_WhenUserDoesNotExist()
{
// Arrange
var dto = new UserDto
{
EmailAddress = "createAsyncTest@email.com",
ExternalId = "externalId2",
Name = "Create Async"
};
var users = new List<User>();
var mock = users.BuildMock();
_userRepositoryMock.Setup(x => x.Find(y => y.ExternalId == dto.ExternalId)).Returns(mock).Verifiable();
var user = UserMapper.GetUserExpression(null).Compile().Invoke(dto);
_userRepositoryMock.Setup(x => x.InsertAsync(user, true, default)).Verifiable();
// Act
var res = await _sut.CreateAsync(dto);
// Assert
Assert.NotNull(res);
_userRepositoryMock.Verify();
}
}
这是我实现通用存储库的方式:
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
internal TestContext _context;
internal DbSet<TEntity> _dbSet;
public Repository(TestContext context)
{
_context = context;
_context.Database.SetCommandTimeout(300);
_dbSet = context.Set<TEntity>();
}
public IQueryable<TEntity> All() => _dbSet;
public IQueryable<TEntity> Find() => All();
public IQueryable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)
{
return _dbSet.Where(predicate);
}
}
这是我的UserService:
public class UserService : IUserService
{
private readonly IRepository<User> _userRepository;
public UserService(IRepository<User> userRepository)
{
_userRepository = userRepository;
}
public async Task<UserDto> CreateAsync(UserDto dto, CancellationToken cancellationToken = default)
{
var existingUser = await GetExistingUser(dto.ExternalId, cancellationToken);
if (existingUser != null)
throw new Exception("User already exists!");
var user = UserMapper.GetUserExpression(null).Compile().Invoke(dto);
await _userRepository.InsertAsync(user, true, cancellationToken);
return UserMapper.GetUserDtoExpression().Compile().Invoke(user);
}
private async Task<User> GetExistingUser(string externalId, CancellationToken cancellationToken = default)
{
return await _userRepository
.Find(x => x.ExternalId == externalId)
.FirstOrDefaultAsync(cancellationToken);
}
}
传递给_userRepositoryMock.Setup()的Expression<Func<User, bool>>
类型谓词与您在_userRepositoryMock.Setup()中指定的表达式不同(它们具有相同的逻辑和相同的externalId,但它们是不同的实例)
不是
_userRepositoryMock.Setup(x => x.Find(y => y.ExternalId == dto.ExternalId)).Returns(mock)
试试这个:
_userRepositoryMock.Setup(x => x.Find(It.IsAny<Expression<Func<User, bool>>>()).Returns(predicate => mock.Where(predicate))
这样,传递给. find()方法的任何表达式都将原样应用于模拟的存储库。