unit test mock framework context c# .net entity-framework unit-testing moq

test - mock dbcontext c#



Simulacro DbContext.set<T>.Add() EF6 (2)

Parece que te estás perdiendo la configuración para devolver tu DbSet :

mockContext.Setup(m => m.Set<Prospect>()).Returns(mockProspect.Object);

Tengo las siguientes clases (donde PilsnerContext es una clase DbContext):

public abstract class ServiceBase<T> : IService<T> where T: class, IEntity { protected readonly PilsnerContext Context; protected ServiceBase(PilsnerContext context) { Context = context; } public virtual T Add(T entity) { var newEntity = Context.Set<T>().Add(entity); Context.SaveChanges(); return newEntity; } } public class ProspectsService : ServiceBase<Prospect> { public ProspectsService(PilsnerContext context) : base(context){} }

Y estoy tratando de hacer una prueba unitaria del método Add burlándose del contexto como:

[TestClass] public class ProspectTest { [TestMethod] public void AddProspect() { var mockProspect = new Mock<DbSet<Prospect>>(); var mockContext = new Mock<PilsnerContext>(); mockContext.Setup(m => m.Prospects).Returns(mockProspect.Object); var prospectService = new ProspectsService(mockContext.Object); var newProspect = new Prospect() { CreatedOn = DateTimeOffset.Now, Browser = "IE", Number = "1234567890", Visits = 0, LastVisitedOn = DateTimeOffset.Now }; prospectService.Add(newProspect); mockProspect.Verify(m=>m.Add(It.IsAny<Prospect>()), Times.Once); mockContext.Verify(m=>m.SaveChanges(), Times.Once); } }

Pero el aseverar:

mockProspect.Verify(m=>m.Add(It.IsAny<Prospect>()), Times.Once);

Está fallando, asumo que es porque estoy usando Context.set (). Add () en lugar de Context.Prospects.Add () en el método Add pero ¿cómo es la forma correcta de pasar esta prueba?

La excepción es:

Expected invocation on the mock once, but was 0 times: m => m.Add(It.IsAny<Prospect>()) No setups configured. No invocations performed.

Gracias por adelantado.


Probé su solución Patrick Quirk, pero recibí un error que me dice que DbContext.Set no es virtual.

Encontré la solución para eso aquí:

¿Cómo burlar los métodos de Entity Framework 6 Async?

Creando una interfaz de DbContext como

public interface IPilsnerContext { DbSet<T> Set<T>() where T : class; }

De esa manera podría burlarme.

¡Gracias!

Esta es mi primera pregunta por cierto, no estoy seguro de si puedo marcar esta pregunta como duplicada o algo así.