Skip to content

ExecuteUpdateAsync not suported with SetProperty with Value Expression #93

@WaffleBuffer

Description

@WaffleBuffer

Hello,

i've been working with MockQueryable for a while now.
Recently i tried the new 9.0.0 version for EntityFramework and NSubstitute in XUnit and dotnet 9 because i have some projects which use ExecuteUpdateAsync.
I saw some PR to add support to ExecuteUpdate so the data in tests are actually updated (which is what i would like).

However when i tried to use it with SetProperty with Value Expression like this

public class Entity
{
    public DateTimeOffset Date { get; set; }
}

public class Test
{
    [Fact]
    public async Task Test1()
    {
        // Arrange
        var entity1 = new Entity
        {
            Date = new DateTimeOffset(2025, 10, 14, 00, 00, 00, TimeSpan.Zero),
        };
        var entity2 = new Entity
        {
            Date = new DateTimeOffset(2026, 10, 14, 00, 00, 00, TimeSpan.Zero),
        };
        List<Entity> entities = [entity1, entity2];
        var mockDbSet = entities.BuildMockDbSet();

        // Act
        await mockDbSet.ExecuteUpdateAsync(e =>
            e.SetProperty(e => e.Date, e => e.Date.AddYears(1))
        );

        // Assert
        Assert.Equal(new DateTimeOffset(2026, 10, 14, 00, 00, 00, TimeSpan.Zero), entity1.Date);
        Assert.Equal(new DateTimeOffset(2027, 10, 14, 00, 00, 00, TimeSpan.Zero), entity2.Date);
    }
}

I get this error

[xUnit.net 00:00:01.05]   Finished:    mockqueryable-issueTests
  mockqueryable-issueTests test failed with 1 error(s) (3.0s)
    /home/thomasmedard/Apollo/Others/mockqueryable-issue/MockQueryableIssueTests/bin/Debug/net9.0/mockqueryable-issueTests.dll : error TESTERROR: 
      MockQueryable.Issue.Tests.Test.Test1 (357ms): Error Message: System.ArgumentException : Object of type 'System.Func`2[MockQueryable.Issue.Tests.Entity,System.DateTimeOffset]'
       cannot be converted to type 'System.DateTimeOffset'.
      Stack Trace:
         at System.RuntimeType.CheckValue(Object& value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
         at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, Object[] index)
         at MockQueryable.EntityFrameworkCore.TestAsyncEnumerableEfCore`2.ApplyUpdateChangesToDbSet(IEnumerable`1 affectedItems, MethodCallExpression methodCallExpression)
         at MockQueryable.EntityFrameworkCore.TestAsyncEnumerableEfCore`2.Execute[TResult](Expression expression)
         at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
         at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)

However if i change my test to use a SetProperty with a fixed value like this

// Act
        await mockDbSet.ExecuteUpdateAsync(e =>
            e.SetProperty(e => e.Date, new DateTimeOffset(2028, 10, 14, 00, 00, 00, TimeSpan.Zero))
        );

        // Assert
        Assert.Equal(new DateTimeOffset(2028, 10, 14, 00, 00, 00, TimeSpan.Zero), entity1.Date);
        Assert.Equal(new DateTimeOffset(2028, 10, 14, 00, 00, 00, TimeSpan.Zero), entity2.Date);

Then the test pass with no exception

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