-
-
Notifications
You must be signed in to change notification settings - Fork 84
Description
Hello!
I've been using MockQueryable with .NET6 a lot
Recently my project migrated to .NET 7 (EF Core 7)
And I started to use new EF7 features:
- ExecuteDeleteAsync
...
.Where(user => user.Id == id)
.ExecuteDeleteAsync();
ExecuteDeleteAsync implementation is here
https://github.com/dotnet/efcore/blob/main/src/EFCore.Relational/Extensions/RelationalQueryableExtensions.cs#L316
- ExecuteUpdateAsync
.Where(user => user.Id == id)
.ExecuteUpdateAsync(updater => updater
.SetProperty(
user => user.Status,
user => status)
.SetProperty(
user => user.ModifiedBy,
user => _userContextProvider.GetUserId())
.SetProperty(
user => user.ModifiedOn,
user => DateTimeOffset.UtcNow));
ExecuteUpdateAsync implementation is here
https://github.com/dotnet/efcore/blob/main/src/EFCore.Relational/Extensions/RelationalQueryableExtensions.cs#L372
I use MockQueryable using a standard pattern:
var mock = users.BuildMock();
_userRepository.Setup(x => x.GetQueryable()).Returns(mock);
ToListAsync(), FirstOrDefaultAsync() and others works perfectly with this pattern.
Unfortunately ExecuteUpdateAsync / ExecuteDeleteAsync doesn't work at all :(
When I try to run a unit test, a mocked GetQueryable method works nicely as usual, but it throws an exception on ExecuteDeleteAsync
<System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
---> System.InvalidOperationException: There is no method 'ExecuteDelete' on type 'Microsoft.EntityFrameworkCore.RelationalQueryableExtensions' that matches the specified arguments
at System.Linq.EnumerableRewriter.FindMethod(Type type, String name, ReadOnlyCollection`1 args, Type[] typeArgs)
at System.Linq.EnumerableRewriter.VisitMethodCall(MethodCallExpression m)
at System.Linq.EnumerableExecutor`1.Execute()
at System.Linq.EnumerableQuery`1.System.Linq.IQueryProvider.Execute[TElement](Expression expression)
at Microsoft.EntityFrameworkCore.RelationalQueryableExtensions.ExecuteDelete[TSource](IQueryable`1 source)
at lambda_method34(Closure)
at MockQueryable.Core.TestQueryProvider`1.CompileExpressionItem[TResult](Expression expression)
at MockQueryable.Core.TestQueryProvider`1.Execute[TResult](Expression expression)
at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
--- End of inner exception stack trace ---
at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at MockQueryable.EntityFrameworkCore.TestAsyncEnumerableEfCore`1.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.RelationalQueryableExtensions.ExecuteDeleteAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
Exception throws here on .Invoke(this, new object[] { expression });
https://github.com/romantitov/MockQueryable/blob/master/src/MockQueryable/MockQueryable.EntityFrameworkCore/TestQueryProviderEfCore.cs#L25
Same exception throws at ExecuteUpdateAsync (but it says There is no method 'ExecuteUpdate' on type 'Microsoft.EntityFrameworkCore.RelationalQueryableExtensions' that matches the specified arguments)
The custom logic pattern doesn't work because ExecuteUpdateAsync / ExecuteDeleteAsync are IQueryable extensions
Thank you very much