Skip to content

MockQueryable.NSubstitute 8.0.0 Breaks .AsQueryable() calls on DbSet<TEntity> #88

@ristogod

Description

@ristogod

This test code here works fine in version 7.0.4-beta.

using Microsoft.EntityFrameworkCore;
using MockQueryable.NSubstitute;

namespace AsQueryableTest;

public class UnitTest1
{
    [Fact]
    public async Task Test1()
    {
        List<Item> items =
        [
            new () { Id = 1 },
            new () { Id = 2 },
            new () { Id = 3 }
        ];

        var itemDbSet = items.BuildMockDbSet();

        var result = await itemDbSet.AsQueryable()
                                    .Where(static item => item.Id == 1)
                                    .CountAsync();

        Assert.Equal(1, result);
    }

    public class Item
    {
        public int Id { get; set; }
    }
}

However, in version 8.0.0, we get this exception:

System.InvalidOperationException
The provider for the source 'IQueryable' doesn't implement 'IAsyncQueryProvider'. Only providers that implement 'IAsyncQueryProvider' can be used for Entity Framework asynchronous operations.
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable`1 source, Expression expression, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable`1 source, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.CountAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
   at AsQueryableTest.UnitTest1.Test1() in ...AsQueryableTest\AsQueryableTestError\UnitTest1.cs:line 20
   at Xunit.Sdk.TestInvoker`1.<>c__DisplayClass47_0.<<InvokeTestMethodAsync>b__1>d.MoveNext() in /_/src/xunit.execution/Sdk/Frameworks/Runners/TestInvoker.cs:line 259
--- End of stack trace from previous location ---
   at Xunit.Sdk.ExecutionTimer.AggregateAsync(Func`1 asyncAction) in /_/src/xunit.execution/Sdk/Frameworks/ExecutionTimer.cs:line 48
   at Xunit.Sdk.ExceptionAggregator.RunAsync(Func`1 code) in /_/src/xunit.core/Sdk/ExceptionAggregator.cs:line 90

Yes, if I remove the .AsQueryable() it works. However, we have production code that makes use of .AsQueryable() from our DbContext.DbSet implementations because there might be ambiguity issues between IQueryable and IEnumerable extensions.

I wasn't sure if I was going to submit this, so I asked fellow developers their opinions and this was some of their thoughts:

"A likely cause is that in 7.0.4-beta, .AsQueryable() returned an instance of TestAsyncEnumerableEfCore, which implements IAsyncQueryProvider. In version 8.0.0, .AsQueryable() no longer returns this type, which results in the loss of IAsyncQueryProvider support.

Since a real DbSet supports AsQueryable() and the purpose of BuildMockDbSet is to mimic DbSet behavior, this is a regression from 7.0.4-beta. So I think this is a bug rather than an intentional design change."

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions