-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
InMemory DbContext does not respect CancellationToken on SaveChangesAsync #13368
Comments
My current workaround for getting my unit tests to behave as expected.
|
The InMemory provider does not make any async calls and therefore does not use the cancellationToken. Internally it it just performs a Task.FromResult inside of SaveChangesAsync |
I assumed as much, however I assume the entire purpose of the InMemory database is to facilitate testing, so I think having behavior closely match other providers would be desirable. |
So it's been a number of years since this was reported and I thought I should mention that I've just run into the same issue. I'm trying to unit test my repository class for cooperative cancellation by making sure it's passing through the CancellationToken to the DbContext. |
See #18457 |
We recommend against using the in-memory provider for testing--see Testing EF Core Applications. While we have no plans to remove the in-memory provider, we will not be adding any new features to this provider because we believe valuable development time is better spent in other areas. When feasible, we plan to still fix regressions in existing behavior. |
Just like to add that you cannot just replace the InMemory database with SQLite as a testing replacement for a SQL Server based context. Whilst new features are available ( Tx ), some are removed... like Concurrency ( timestamp/rowversion ) support. The suggested "solution" involves modifying the real code under test if running SQLite - not an acceptable approach IMHO. If the InMemory is removed, EF based solution may become untestable in some circumstances. Please respect the cancellationToken in the InMemory provider... it's a real simple check. It avoids us from having to insert "ThrowIfCancellationRequested()" everywhere our code because we want to test exception handling. The debate about a suitable test DB engine replacement for Unit tests is not a simple one, but all DB providers MUST respect cancellation tokens in all async methods. |
FWIW this isn't quite true; cancellation in general is a best-effort, race-sensitive mechanism - there's never any 100% guarantee that cancellation will actually work, and your code and tests generally shouldn't rely on that. It's true that in many cases, calling a method with a cancelled token immediately causes an OperationCanceledException to be thrown, but this isn't a hard rule; for example, if the method doesn't need to complete any I/O (e.g. since data isn't buffered in memory), then it's reasonable for it to just complete rather than throw. Note that I'm not saying that InMemory necessarily shouldn't throw when passed a cancelled token, but it's just another example of why using InMemory for testing isn't a good choice. If you want to test that your application code actually passes the cancellation token to EF's SaveChangesAsync, I'd consider mocking DbContext and asserting via the mock that the token was received. |
When using an InMemory DbContext, the
SaveChangesAsync
does not respect the cancellation token being passed in.Steps to reproduce
Setting
, expose aDbSet<Settings>
Further technical details
EF Core version
Database Provider
Operating system
IDE
The text was updated successfully, but these errors were encountered: