2011-06-14 23 views
12

prueba de unidad nueva. Tengo una unidad de trabajo que estoy tratando de probar por unidad. Probablemente me esté perdiendo algo simple aquí. Estoy tratando de probar la unidad del método Commit. Estoy usando nunit y moq.unidad que prueba una unidad de trabajo

public class UnitOfWork : IUnitOfWork 
{ 
    private readonly DbContext _context; 
    public UnitOfWork(DbContext ctx) 
    { 
     _context = ctx; 
    } 

    public void Commit() 
    { 
     _context.SaveChanges(); 
    } 
} 

¿Qué debo hacer para probar esto?

Respuesta

16

Debería insertar una simulación del DBContext y luego verificar que el método SaveChanges se invoque en commit.

[Test] 
public void Will_call_save_changes() { 

    var mockContext = new Mock<DBContext>(); 
    var unitOfWork = new UnitOfWork(mockContext.Object); 

    unitOfWork.Commit(); 


    mockContext.Verify(x => x.SaveChanges()); 

} 
1

Deberá burlarse del DbContext y luego verificar que se haya llamado a SaveChanges. Algo como Moq puede ayudarte aquí.

0

Esa es una forma de hacerlo.

Una alternativa que he encontrado es:

crear el archivo edmx, retire la herramienta personalizada para que no se AutoGenerate las entidades.

Abra el archivo edmx, haga clic derecho y agregue el elemento de generación de código - vaya a plantillas en línea en la base de datos y seleccione el generador de objetos de simulación EF POCO. Esto crea dos plantillas T4 (una para entidades y otra para el contexto del objeto y el contexto del objeto simulado).

La única plantilla T4 generará sus entidades poco para usted. La otra plantilla T4 creará una interfaz que puede ampliar para ser utilizada como una unidad de trabajo que se implementa en un contexto de objeto real y un contexto de objeto simulado. Extenderlo solo requiere que modifique la plantilla T4 para incluir un método adicional en la interfaz generada (void SaveChanges()) y la implementación de ese método en el contexto del objeto simulado.

He encontrado que funciona muy bien.

Aunque para fines de pruebas unitarias, no querrá probar su unidad de trabajo (a menos que verifique que ciertos objetos se agreguen o eliminen, etc.). En cambio, debería probar repositorios con responsabilidades predefinidas, generalmente definidas dentro del contexto (por ejemplo, citas con el paciente).

usted haría algo como esto:

public class PatientAppointmentRepository : IPatientAppointmentRepository 
{ 
    //Injected via IOC in constructor 
    private readonly IUnitOfWork _unitOfWork; 
    private readonly IPatientAppointmentLogic _patientAppointmentLogic; 
    public void CreateAppointment(PatientAppointmentModel model) 
    { 
     var appointment = ModelMapper.Instance.To<PatientAppointment>(model); 

     var appointmentAdded = _patientAppointmentLogic.Add(appointment); 

     if(appointmentAdded) 
      _unitOfWork.SaveChanges(); 
    } 
} 

public class PatientAppointmentLogic : IPatientAppointmentLogic 
{ 
    private readonly IUnitOfWork _unitOfWork; //Set via constructor 
    private readonly PatientLogic _patientLogic; 
    public bool Validate(PatientAppointment appointment) 
    { 
     if(appointment == null) 
      throw new ArgumentNullException("appointment"); 

     //perform some logic here 
     return true; 
    } 
    public void Add(PatientAppointment appointment) 
    { 
     if(appointment == null) 
      throw new ArgumentNullException("appointment"); 

     if(!Validate(appointment)) return; //Or throw an exception, up to you 

     var patient = _patientLogic.GetById(appointment.PatientId); 

     if(patient == null) return; 

     patient.PatientAppointments.Add(appointment); 
    } 
} 

Es realmente depende de su estructurarlo apropiadamente. Podría tener otro repositorio AppointmentLogic que tenga una validación base como ejemplo.

Idealmente, la validación genérica no debería depender de recursos externos (como una base de datos).

Debería poder crear un contexto de validación de una sola vez que se usaría en posteriores validación (primero válido 'a bajo costo' antes de validar 'caro').

A veces, todos los "valores" que necesita para la validación están dentro de una entidad que necesitaría de todos modos, y luego la usa como contexto de validación.

¡La mejor de las suertes!