2008-12-11 16 views
8

He usado Moq para burlarme de mi repositories. Sin embargo, alguien dijo recientemente que prefieren crear implementaciones de prueba codificadas de sus interfaces de repositorio.¿Cómo te burlas de tus repositorios?

¿Cuáles son los pros y los contras de cada enfoque?

Edit: aclarado significado de repositorio con enlace a Fowler.

Respuesta

6

generalmente veo dos escenarios con los repositorios. Pido algo, y lo entiendo, o pido algo, y no está allí.

Si se burla de su repositorio, significa que su sistema bajo prueba (SUT) es algo que está utilizando su repositorio. Por lo tanto, generalmente quiere probar que su SUT se comporta correctamente cuando recibe un objeto del repositorio. Y también quiere probar que maneja la situación adecuadamente cuando espera recuperar algo y no lo hace, o no está seguro si va a recuperar algo.

Los dobles de prueba codificados están bien si está realizando pruebas de integración. Diga, quiere guardar un objeto y luego recuperarlo. Pero esto está probando la interacción de dos objetos juntos, no solo el comportamiento del SUT. Son dos cosas diferentes. Si comienza a codificar repositorios falsos, también necesita pruebas unitarias para ellos, de lo contrario terminará basando el éxito y el fracaso de su código en código no probado.

Esa es mi opinión sobre Mocking vs. Test Doubles.

0

Supongo que por "repositorio" te refieres a DAO; si no, esta respuesta no se aplicará.

Últimamente he estado realizando implementaciones "en memoria" "simuladas" (o de prueba) de mi DAO, que básicamente operan sin datos (una Lista, Mapa, etc.) pasados ​​al constructor de la simulación. De esta manera, la clase de prueba de la unidad puede arrojar cualquier dato que necesite para la prueba, puede cambiarlo, etc., sin forzar que todas las pruebas de la unidad que operan en el DAO "en memoria" se codifiquen para usar los mismos datos de prueba.

Una ventaja que veo en este enfoque es que si tengo una docena de pruebas unitarias que necesitan usar el mismo DAO para su prueba (para inyectar en la clase bajo prueba, por ejemplo), no necesito recuerde todos los detalles de los datos de prueba cada vez (como lo haría si el "simulacro" estuviera codificado) - la prueba unitaria crea los datos de prueba en sí. En el lado negativo, esto significa que cada prueba unitaria tiene que gastar unas pocas líneas creando y conectando sus datos de prueba; pero eso es un pequeño inconveniente para mí.

un ejemplo de código:

public interface UserDao { 
    User getUser(int userid); 
    User getUser(String login); 
} 

public class InMemoryUserDao implements UserDao { 

    private List users; 

    public InMemoryUserDao(List users) { 
     this.users = users; 
    } 

    public User getUser(int userid) { 
     for (Iterator it = users.iterator(); it.hasNext();) { 
      User user = (User) it.next(); 
      if (userid == user.getId()) { 
       return user; 
      } 
     } 

     return null; 
    } 

    public User getUser(String login) { 
     for (Iterator it = users.iterator(); it.hasNext();) { 
      User user = (User) it.next(); 
      if (login.equals(user.getLogin())) { 
       return user; 
      } 
     } 

     return null; 
    } 
} 
+0

Me refiero al patrón de repositorio. He editado la pregunta con un enlace a la definición de Martin Fowler. –

6

SCNR: "?! Usted se llama un repositorio que he visto cajas de cerillas con más capacidad"

+0

Eso es lo primero que pensé cuando leí la pregunta :-) – Ferruccio

+1

Gracias por esta respuesta. Me salvó el esfuerzo. –

Cuestiones relacionadas