Created
June 14, 2023 07:21
-
-
Save ctrl-alt-d/3d10384a06fa1e0c515e1f182fb83bb0 to your computer and use it in GitHub Desktop.
Mocking EF in the wrong way
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace efsetp; | |
using Microsoft.EntityFrameworkCore; | |
using Microsoft.EntityFrameworkCore.ChangeTracking; | |
using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; | |
using Microsoft.EntityFrameworkCore.Metadata; | |
using Moq; | |
public class Customer | |
{ | |
public int CustomerId { get; set; } | |
public string Name { get; set; } = ""; | |
} | |
public class CustomerRepository | |
{ | |
protected readonly DbContext DbContext; | |
public CustomerRepository(DbContext dbContext) | |
{ | |
DbContext = dbContext; | |
} | |
public virtual void Delete<TEntity>(TEntity entity) | |
where TEntity: class | |
{ | |
var entry = DbContext.Entry(entity); | |
if (entry.State == EntityState.Detached) | |
{ | |
DbContext.Attach(entity); | |
} | |
DbContext.Remove(entity); | |
} | |
} | |
public class UnitTest1 | |
{ | |
[Fact] | |
public void Delete_SomeEntityToRepository_CallsTheAddMethod_To_DbContext() | |
{ | |
// Arrange | |
var testObject = new Customer(); | |
var internalEntityEntry = GetInternalEntityEntry(testObject); | |
var dbEntityEntryMock = new Mock<EntityEntry<Customer>>(internalEntityEntry); | |
dbEntityEntryMock.Setup(e => e.State).Returns(EntityState.Unchanged); | |
var dbContextMock = new Mock<DbContext>(); | |
dbContextMock.Setup(d => d.Entry(testObject)).Returns(dbEntityEntryMock.Object); | |
// Act | |
var repository = new CustomerRepository(dbContextMock.Object); | |
repository.Delete(testObject); | |
//Assert | |
dbContextMock.Verify(x => x.Remove(It.Is<Customer>(y => y == testObject)), Times.AtMost(1)); | |
} | |
private static InternalEntityEntry GetInternalEntityEntry(Customer testObject) | |
{ | |
return new InternalEntityEntry( | |
new Mock<IStateManager>().Object, | |
new RuntimeEntityType( | |
name: nameof(Customer), | |
type: typeof(Customer), | |
sharedClrType: false, | |
model: new(), | |
baseType: null, | |
discriminatorProperty: null, | |
changeTrackingStrategy: ChangeTrackingStrategy.Snapshot, | |
indexerPropertyInfo: null, | |
propertyBag: false, | |
discriminatorValue: null), | |
testObject); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment