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

Fixed GetEnumerator() method on mock #3999

Merged
merged 1 commit into from
Aug 25, 2022
Merged

Fixed GetEnumerator() method on mock #3999

merged 1 commit into from
Aug 25, 2022

Conversation

mjeldreth
Copy link
Contributor

Currently the underlying data collection's GetEnumerator() is only invoked once, and the resulting value is used every time the mocked DbSet's GetEnumerator() method is invoked. The mocked DbSet needs to be configured to retrieve a new enumerator each time the method is called by invoking the underlying data collection's GetEnumerator() method. Otherwise the enumerator returned by the method will become invalid if the contents of the mocked DbSet change.

Since the example sets up the underlying data before configuring the mock, and doesn't make any subsiquent changes after that point, this doesn't cause any issues in the example. But if the same setup code is used in a unit test that involves modifying the contents of the DbSet, the code will throw InvalidOperationExceptions anytime the DbSet is iterated through or ToList() is called.

The Mock<IQueryable> needs to be configured to call the underlying collection's `GetEnumerator()` method every time it is invoked. As it is currently written, the method is only invoked once (during setup) to get a single value and that value is returned each time `GetEnumerator()` is called. This causes issues if the underlying data collection is changed by adding and/or removing items. Doing so results in the enumerator becoming stale and causes Invalid Operation Exceptions if you try to iterate through the IQueryable or call extension methods like  `ToList()` or `ToArray()`
Copy link
Member

@roji roji left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, yeah - this sample was only meant to work for the specific, constrained scenario... but you're right that users may copy-paste this and be surprised when it doesn't work.

@roji roji merged commit c3d4ef9 into dotnet:main Aug 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants