2010-10-22 15 views
8

Tenga en cuenta que esto puede sonar como una pregunta amplia, así que déjenme aclarar. Tengo un repositorio expuesto a través de una interfaz, con dos implementaciones concretas: MockRepository y EntityFrameworkRepository.¿Cómo hacer una prueba de unidad de las operaciones de CRUD en un repositorio?

Ahora, tengo un proyecto Unit-Test para el cual todas las pruebas se pueden ejecutar contra el repositorio ya sea, pasando rápidamente una línea en [TestInitialize].

Mi pregunta es básicamente "¿Cómo debo escribir las pruebas".

Esto es lo que tengo:

C reate

// Arrange. 
var foo = new Foo { .. }; 

// Act 
Repository.Add(foo); 
UnitOfWork.Commit(); 

// Assert 
Assert.IsTrue(foo.Id > 0); 

R ECUPERACIÓN D E U

// Arrange. 
var fooToGet = 1; 

// Act 
var foo = Repository.FindSingle(fooToGet); 

// Assert 
Assert.IsNotNull(foo); 
Assert.AreEqual(foo.Id, fooToGet); 

T pdate

// Arrange. 
var fooToGet = 1; 
var nameToChangeFooTo = "FooBar"; 

// Act 
var foo = Repository.FindSingle(fooToGet); 
foo.Name = nameToChangeFooTo; 
UnitOfWork.Commit(); 
var fooRetrievedAgain = Repository.FindSingle(fooToGet); 

// Assert 
Assert.IsNotNull(foo); 
Assert.AreEqual(fooRetrievedAgain.Id, fooToGet); 
Assert.AreEqual(fooRetrievedAgain.Name, nameToChangeFooTo); 

D elete

// Arrange. 
var fooToGet = 1; 

// Act 
var foo = Repository.FindSingle(fooToGet); 
Repository.Remove(foo); 
UnitOfWork.Commit(); 
var fooRetrievedAgain = Repository.FindSingle(fooToGet); 

// Assert 
Assert.IsNull(fooRetrievedAgain); 

que está funcionando bien , tanto para el Mock y el repositorio de EF, pero mi principal problema es C (Crear). No estoy seguro de cómo probar una operación Agregar en mi repositorio. No es se siente bien lo que estoy haciendo.

Pasa para el Repositorio de EF, pero para hacerlo pasar en mi Repositorio de Mock tuve que usar el reflejo para actualizar el ID en la colección en memoria (desagradable).

Entonces, ¿podría compartir algunos consejos sobre cuáles son las formas correctas de probar las operaciones CRUD en el patrón de repositorio?

Esta es una aplicación MVC de ASP.NET, .NET 4, C#, Entity Framework 4 y patrones de unidad de trabajo/repositorio.

Gracias.

EDITAR

sólo para aclarar chicos, estos no son todos los unidad de pruebas que tengo. Tengo pruebas de unidad para mi capa de servicio, así como pruebas de reglas de negocio.

Ambos últimos fallarán (y deberían) si mis pruebas de Repositorio anteriores fallan. Ese es el punto aquí, para probar la unidad operaciones muy básicas de mis repositorios. ¿Me equivoco?

+0

¿Qué estás probando aquí? Huele como si estuvieras probando por escribir pruebas. – jfar

+0

@jfar - de hecho, escribí esas pruebas antes de implementar los repositorios (TDD). ¿Estás diciendo que no te molestas en probar tus repositorios? Piense en cuántos errores "sin sentido" se encontrarían en las pruebas comerciales/del sistema. Uno que se puede (y se debe) resaltar durante un testrun con una construcción de CI. ¿No crees? – RPM1984

+0

Y recuerde, estoy probando a través de 'interfaces'. 'Repository' es de tipo' IRepository '. Por lo tanto, lo único que intento hacer es garantizar que mis repositorios puedan realizar operaciones básicas en un almacén de persistencia (ya sea que ese almacén sea un repositorio simulado en memoria o un repositorio EF). – RPM1984

Respuesta

3

Una opción es usar una base de datos en memoria como SqlLite para probar el comportamiento de sus asignaciones, consultas y repositorios. Esto es discutido por Ayende here, aunque su ejemplo usa NHibernate.

Otra opción que parece abordar su preocupación inmediata de establecer los Id. De los objetos de dominio es usar pruebas falsas.Esto es discutido por RhysC here.

+0

Piensa que has malinterpretado mi pregunta. Ya tengo un Repositorio Simulado en su lugar, estoy preguntando cómo puedo escribir pruebas que deben pasar en contra de los Repositorios Simulado y Real. Mira el método de prueba de Ayende. Esa es la información que quiero (cómo escribir la prueba correctamente), no el detalle de la implementación real. – RPM1984

+1

Si el repositorio no contiene ninguna lógica complicada y simplemente reenvía las solicitudes a la tienda subyacente.Entonces, una prueba basada en la interacción en lugar de una basada en el estado podría ser más apropiada. es decir, burlarse de la tienda que se inyecta en el repositorio. Y afirmar que ciertos métodos fueron llamados en él. En lugar de afirmar sobre el valor de la id de objeto de dominio. – martinl

+0

Respuesta aceptada, ya que nos estamos moviendo a SqlLite para pruebas en memoria (aunque es integración, de tipo) – RPM1984

1

OMI, su prueba de crear debe:

  • añadir una entidad al repositorio
  • afirman que fue asignado un ID
  • recuperar la entidad insertada utilizando el ID de
  • comparar la entidad inicial con la entidad de lectura y asegúrese de que sus propiedades sean las mismas

Tengo muchas pruebas unitarias como la suya la principal d La diferencia es que estoy usando un método de comparación profundo para comparar instancias de objetos. Por ejemplo, mis pruebas U se ven así:

  • añadir una entidad al repositorio
  • recuperar la entidad insertada utilizando el ID de
  • cambiar algunas de las propiedades de la entidad
  • actualización de la entidad en el repositorio
  • recuperar la entidad actualizada utilizando el ID
  • comparar la entidad actualizada con la entidad de lectura y asegurarse de que sus propiedades sean las mismas (puede definir una lógica específica para las propiedades que no son actualizables)
+0

Interesante. Aunque su U (Actualización) también prueba un complemento. ¿Es eso realmente una prueba de unidad? El resto de su prueba U tiene sentido, pero no la suma de la primera. IMO, una prueba de actualización debería implicar recuperar un elemento existente y luego actualizarlo. Sin embargo, tu respuesta (y tus pensamientos) son bienvenidos. Gracias. – RPM1984

+1

Veo su punto, pero si no inserta la entidad, debe confiar en un estado previo que podría haber sido creado por un ClassInitialize, por ejemplo. Realmente prefiero que mis pruebas sean atómicas. Además, tenga en cuenta que no estoy probando nada en la entidad insertada. –

+0

En realidad, sí, ese es un gran punto. La prueba debe ser atómica. – RPM1984

Cuestiones relacionadas