public async Task SaveChangesAsync_only_passes_dirty_entries_to_Database() { var passedEntries = new List<IUpdateEntry>(); var database = new Mock<IDatabase>(); database.Setup(s => s.SaveChangesAsync(It.IsAny<IReadOnlyList<IUpdateEntry>>(), It.IsAny<CancellationToken>())) .Callback<IEnumerable<IUpdateEntry>, CancellationToken>((e, c) => passedEntries.AddRange(e)) .Returns(Task.FromResult(3)); var valueGenMock = new Mock<IValueGeneratorSelector>(); valueGenMock.Setup(m => m.Select(It.IsAny<IProperty>(), It.IsAny<IEntityType>())).Returns(Mock.Of<ValueGenerator>()); var servicesMock = new Mock<IDatabaseProviderServices>(); servicesMock.Setup(m => m.Database).Returns(database.Object); servicesMock.Setup(m => m.ValueGeneratorSelector).Returns(valueGenMock.Object); servicesMock.Setup(m => m.ModelSource).Returns(new Mock<ModelSource>(new DbSetFinder(), new CoreConventionSetBuilder()) { CallBase = true }.Object); servicesMock .Setup(m => m.ModelValidator) .Returns(new LoggingModelValidator(new Logger<LoggingModelValidator>(new LoggerFactory()))); var sourceMock = new Mock<IDatabaseProvider>(); sourceMock.Setup(m => m.IsConfigured(It.IsAny<IDbContextOptions>())).Returns(true); sourceMock.Setup(m => m.GetProviderServices(It.IsAny<IServiceProvider>())).Returns(servicesMock.Object); var services = new ServiceCollection(); services.AddEntityFramework(); services.AddInstance(sourceMock.Object); var serviceProvider = services.BuildServiceProvider(); using (var context = new EarlyLearningCenter(serviceProvider, new DbContextOptionsBuilder().Options)) { context.Entry(new Category { Id = 1 }).State = EntityState.Unchanged; context.Entry(new Category { Id = 2 }).State = EntityState.Modified; context.Entry(new Category { Id = 3 }).State = EntityState.Added; context.Entry(new Category { Id = 4 }).State = EntityState.Deleted; Assert.Equal(4, context.ChangeTracker.Entries().Count()); await context.SaveChangesAsync(); } Assert.Equal(3, passedEntries.Count); database.Verify( s => s.SaveChangesAsync(It.IsAny<IReadOnlyList<InternalEntityEntry>>(), It.IsAny<CancellationToken>()), Times.Once); }