Hi,
I want to test the EditPost method of controllers. To simulate database access, I use Microsoft.EntityFrameworkCore.InMemory.
But if I use Microsoft.EntityFrameworkCore.InMemory, I have to do something like this (for a given test):
[Fact]
public void Can_Edit_Customer_Email()
{
// Generate the needed data from Microsoft.EntityFrameworkCore.InMemory
DataGenerator();
// Arrange
var customer = _context.Customers.Find(1);
// Act
customer.EmailContact = "john.doe@contoso.com";
HomeController target = new HomeController(_context);
target.EditPost(1, customer);
// Assert
Assert.Equal("john.doe@contoso.com", _context.Customers.Find(1).EmailContact);
}
Otherwise, if I feed the target.EditPost method like this:
// Act
HomeController target = new HomeController(_context);
target.EditPost(1, new Customer {Id = 1, FirstName = "John", LastName = "Doe", Email = "john.doe@contoso.com"});
I get this "expected" exception:
System.InvalidOperationException : The instance of entity type 'Customer' cannot be tracked because another instance with the key value 'Id:1' is already being tracked. When attaching existing entities,
ensure that only one entity instance with a given key value is attached.
With a real database, my controllers work as expected (as detached). I mean, the entities start to be tracked when I retrieve them in the EditPost() method, and stopped to be tracked
when _context.SaveChanges() is called.
But in the Microsoft.EntityFrameworkCore.InMemory context, entities are tracked as soon as they are added (here with my DataGenerator() method), and nothing seems to be reset, when _context.SaveChanges() is called. So I get the aboveSystem.InvalidOperationException;
While the "Find() method etc…" way works fine, it does not reproduce the "actual context" of data submission (with all that implies, like test accuracy, etc).
So my question is:
- How can I reproduce disconnected scenario during my tests with Microsoft.EntityFrameworkCore.InMemory? I mean, how can I reset change tracking when _context.SaveChanges() is called?