迁移到.net核心3并添加TResult IAsyncQueryProvider

时间:2019-08-01 18:19:29

标签: c#

我做了类似的事情: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中的测试

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)并返回。