Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
527 views
in Technique[技术] by (71.8m points)

c# - IAsyncQueryProvider mock issue when migrated to .net core 3 adding TResult IAsyncQueryProvider

I did something similar to : How to mock an async repository with Entity Framework Core in one of my unit test project .net core 2.1. Now trying to update it to 3.0 preview and have some error with IAsyncQueryProvider.

So when I updated my project. i had some issue with my unit tests. In fact,IAsyncEnumerable switched GetEnumerator for GetAsyncEnumerator. Fixed that. Moreovere some interfaces changed and had to be implemented in my code.

My issue here its with IAsyncQueryProvider witch added TResult IAsyncQueryProvider.ExecuteAsync(Expression expression, CancellationToken cancellationToken) and i don't know what to do with this because since I updated to getAsyncEnumerator i go in this part of my code and can t make it work because i don't know how to return TResult I've tried: 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();
    }

my test should be passing as it was in .net core 2.1

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I've found a library that has successfully upgraded this mock implementation to .NET Core 3.0: https://github.com/romantitov/MockQueryable/blob/master/src/MockQueryable/MockQueryable.EntityFrameworkCore/TestQueryProviderEfCore.cs (note that the code in the github repo has changed since the snippet below was posted).

The interface for Execute was replaced with ExecuteAsync in the IdentityServer upgrade.

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});
}

The executionResult is the evaluation of the expression and then is wrapped in a task (with some reflection to make it generic) Task.FromResult(executionResult) and returned.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...