我做了类似的事情:How to mock an async repository with Entity Framework Core 在我的单元测试项目之一.net core 2.1中。现在尝试将其更新为3.0预览,并使用IAsyncQueryProvider出现一些错误。
所以当我更新项目时。我的单元测试有问题。实际上,IAsyncEnumerable将GetEnumerator切换为GetAsyncEnumerator。固定的。而且,某些接口已更改,必须在我的代码中实现。
我这里的问题与IAsyncQueryProvider一起添加了TResult IAsyncQueryProvider.ExecuteAsync(Expression expression,CancellationToken cancelledToken),我不知道该怎么办,因为自从我更新到getAsyncEnumerator之后,我进入了代码的这一部分,并且不能使它工作,因为我不知道如何返回TResult
我试过了:
return Execute<TResult>(expression);
return _inner.Execute<TResult>(expression);
throw new NotImplementedException();(:p sorry had to)
internal class TestAsyncQueryProvider<TEntity> : IAsyncQueryProvider
{
private readonly IQueryProvider _inner;
internal TestAsyncQueryProvider(IQueryProvider inner)
{
_inner = inner;
}
public IQueryable CreateQuery(Expression expression)
{
return new TestAsyncEnumerable<TEntity>(expression);
}
public IQueryable<TElement> CreateQuery<TElement>(Expression expression)
{
return new TestAsyncEnumerable<TElement>(expression);
}
public object Execute(Expression expression)
{
return _inner.Execute(expression);
}
public TResult Execute<TResult>(Expression expression)
{
return _inner.Execute<TResult>(expression);
}
public IAsyncEnumerable<TResult> ExecuteAsync<TResult>(Expression expression)
{
return new TestAsyncEnumerable<TResult>(expression);
}
public Task<TResult> ExecuteAsync<TResult>(Expression expression, CancellationToken cancellationToken)
{
return Task.FromResult(Execute<TResult>(expression));
}
TResult IAsyncQueryProvider.ExecuteAsync<TResult>(Expression expression, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
我的测试应该通过.net core 2.1中的测试
答案 0 :(得分:3)
我发现一个库已成功将此模拟实现升级到.NET Core 3.0: https://github.com/romantitov/MockQueryable/blob/master/src/MockQueryable/MockQueryable/TestAsyncEnumerable.cs
在IdentityServer升级中,Execute
的接口已替换为ExecuteAsync
。
public TResult ExecuteAsync<TResult>(Expression expression, CancellationToken cancellationToken)
{
var expectedResultType = typeof(TResult).GetGenericArguments()[0];
var executionResult = typeof(IQueryProvider)
.GetMethod(
name: nameof(IQueryProvider.Execute),
genericParameterCount: 1,
types: new[] {typeof(Expression)})
.MakeGenericMethod(expectedResultType)
.Invoke(this, new[] {expression});
return (TResult) typeof(Task).GetMethod(nameof(Task.FromResult))
?.MakeGenericMethod(expectedResultType)
.Invoke(null, new[] {executionResult});
}
executionResult
是对expression
的求值,然后将其包装在一个任务中(进行一些反射以使其通用)Task.FromResult(executionResult)
并返回。