Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ArgumentNullException when verifying method call on EF Core mocked DbContext when the method has not been actually invoked but some DbSet setter has #741

Closed
MichaelSagalovich opened this issue Jan 5, 2019 · 3 comments
Labels
Milestone

Comments

@MichaelSagalovich
Copy link

MichaelSagalovich commented Jan 5, 2019

I reproduced the issue here, and probably that's enough to understand it: https://github.com/MichaelSagalovich/MoqEntityFrameworkIssueReproduction

Formal Steps:

  1. Create a mock of an EF Core context with at least one DbSet property
  2. Assign any value to any DbSet property (actually, null and It.IsAny did not work for me, I used another mock)
  3. Call Verify method on EF Core context mock to verify invocation of any db context method (e.g., Add)

Expected:
4. Descriptive message that no expected invocation has been made, listing all invocations actually made

Actual:
4. ArgumentNullException.

Test Name: Test
Test FullName: MoqEntityFrameworkIssueReproduction.UnitTest.Test
Test Source: ...\MoqEntityFrameworkIssueReproduction\MoqEntityFrameworkIssueReproduction\UnitTest.cs : line 24
Test Outcome: Failed
Test Duration: 0:00:00,728

Result StackTrace:
at Microsoft.EntityFrameworkCore.Utilities.Check.NotNull[T](T value, String parameterName)
at Microsoft.EntityFrameworkCore.ModelExtensions.FindEntityType(IModel model, Type type)
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.get_EntityType()
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.get_EntityQueryable()
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.System.Collections.IEnumerable.GetEnumerator()
at Moq.StringBuilderExtensions.AppendValueOf(StringBuilder stringBuilder, Object obj) in C:\projects\moq4\src\Moq\StringBuilderExtensions.cs:line 71
at Moq.Invocation.ToString() in C:\projects\moq4\src\Moq\Invocation.cs:line 138
at System.String.JoinCore[T](Char* separator, Int32 separatorLength, IEnumerable`1 values)
at System.String.Join[T](String separator, IEnumerable`1 values)
at Moq.MockException.g__FormatInvocations|2_1(<>c__DisplayClass2_0& ) in C:\projects\moq4\src\Moq\MockException.cs:line 93
at Moq.MockException.NoMatchingCalls(String failMessage, IEnumerable`1 setups, IEnumerable`1 invocations, LambdaExpression expression, Times times, Int32 callCount) in C:\projects\moq4\src\Moq\MockException.cs:line 76
at Moq.Mock.VerifyCalls(Mock targetMock, InvocationShape expectation, LambdaExpression expression, Times times, String failMessage) in C:\projects\moq4\src\Moq\Mock.cs:line 378
at Moq.Mock.VerifyNonVoid(Mock mock, LambdaExpression expression, Times times, String failMessage) in C:\projects\moq4\src\Moq\Mock.cs:line 296
at Moq.Mock`1.Verify[TResult](Expression`1 expression) in C:\projects\moq4\src\Moq\Mock.Generic.cs:line 450
at MoqEntityFrameworkIssueReproduction.UnitTest.Test() in ...\MoqEntityFrameworkIssueReproduction\MoqEntityFrameworkIssueReproduction\UnitTest.cs:line 34
Result Message:
System.ArgumentNullException : Value cannot be null.
Parameter name: model

As far as I see, this is caused by Moq trying to 'textualize' all invocations and EF not being able to provide a textual description of its property if not properly configured.

Suggestion: handle exceptions in Invocation.ToString to ensure that a correct verification exception is thrown and an as valid as possible message is still displayed. The issue is wider than just EF Core mocking, as can happen in multiple similar situations.

@stakx stakx added the bug label Jan 5, 2019
@stakx stakx added this to the 4.11.0 milestone Jan 5, 2019
@icenine457
Copy link

Got bit by this bug in a recent unit test mocking the Remove() method attempting to verify that the "Remove()" method on an EF Core DbContext object was not called (Times.Never). Thanks @MichaelSagalovich for being so thorough in your reproduction of the issue!

@stakx
Copy link
Contributor

stakx commented Feb 12, 2019

Btw. for those using EF Core, you might be better off using EF Core's in-memory database provider and testing against that, instead of mocking a live DbContext (which is difficult to do and often goes wrong).

@icenine457
Copy link

icenine457 commented Feb 12, 2019

Thanks @stakx; in light of this issue our team will definitely consider using it instead.
*EDIT: Some clean-up

stakx added a commit to stakx/moq that referenced this issue Mar 10, 2019
...by only showing the first 10 items of enumerables for certain safe
collection types (arrays and `List<T>`). It cannot be generally assum-
ed that `IEnumerable` actually work.

I cannot easily add the test case provided in devlooped#741 to the regression
test suite as it relies on EF Core, and the test project already uses
EF, so we'd likely have type conflicts if both of them are referenced.
stakx added a commit to stakx/moq that referenced this issue Mar 10, 2019
...by only showing the first 10 items of enumerables for certain safe
collection types (arrays and `List<T>`). It cannot be generally assum-
ed that `IEnumerable` actually work.

I cannot easily add the test case provided in devlooped#741 to the regression
test suite as it relies on EF Core, and the test project already uses
EF, so we'd likely have type conflicts if both of them are referenced.
stakx added a commit to stakx/moq that referenced this issue Mar 10, 2019
...by only showing the first 10 items of enumerables for certain safe
collection types (arrays and `List<T>`). It cannot be generally assum-
ed that `IEnumerable` actually work.

I cannot easily add the test case provided in devlooped#741 to the regression
test suite as it relies on EF Core, and the test project already uses
EF, so we'd likely have type conflicts if both of them are referenced.
stakx added a commit that referenced this issue Mar 10, 2019
...by only showing the first 10 items of enumerables for certain safe
collection types (arrays and `List<T>`). It cannot be generally assum-
ed that `IEnumerable` actually work.

I cannot easily add the test case provided in #741 to the regression
test suite as it relies on EF Core, and the test project already uses
EF, so we'd likely have type conflicts if both of them are referenced.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants