2009-07-06 18 views
7

Ejemplo¿Debo escribir una prueba unitaria para un método dentro de la clase de servicio que solo llame a un método dentro de la clase de repositorio?

tengo una clase repositorio (DAL):

public class MyRepository : IMyRepository 
{ 
    public void Delete(int itemId) 
    { 
     // creates a concrete EF context class 
     // deletes the object by calling context.DeleteObject() 
    } 

    // other methods 
} 

También tengo una clase de servicio (BLL):

public class MyService 
{ 
    private IMyRepository localRepository; 

    public MyService(IMyRepository instance) 
    { 
     this.localRepository = instance; 
    } 

    public void Delete(int itemId) 
    { 
     instance.Delete(itemId); 
    } 

    // other methods 
} 

Creación de una unidad de prueba para MyRepository tomaría mucho más tiempo que implementarlo, porque tendría que burlarme del contexto de Entity Framework.

Pero la creación de una prueba unitaria para MyService parece una tontería, ya que solo llama al Repositorio. Todo lo que pude verificar es verificar si realmente llamó al método de repositorio Delete.

Pregunta

¿Cómo sugieren a prueba de unidad este par de métodos de eliminación. ¿Ambos? ¿Uno? ¿Ninguna? ¿Y qué probarías?

Respuesta

1

Sí, definitivamente escribiría una prueba unitaria para la capa de servicio. La razón de esto es porque, no solo está probando que su implementación funciona ahora, sino que también está probando que continuará funcionando en el futuro.

Este es un concepto vital para comprender. Si alguien viene más tarde y cambia su ServiceLayer, y no hay una prueba unitaria, ¿cómo puede verificar que la funcionalidad continúe funcionando?

También escribiría pruebas para su DAL, pero las pondría en un ensamble separado llamado DataTests o algo así. El propósito aquí es aislar sus preocupaciones en las asambleas. En realidad, las pruebas unitarias no deberían preocuparse por su DAL.

+0

Pero si pruebo el método Service.Delete() de la unidad, todo lo que puedo hacer es verificar que llame al método Repository.Delete(). No puedo verificar ningún dato, porque la manipulación de datos se realiza en el repositorio. Otras complejidades (futuras) no se incluirán en la prueba. –

+1

@Robert Eso no es del todo correcto. Debería crear un objeto simulado IMyRepository. Una vez que haya hecho eso, puede configurar su simulacro para que cuando la capa de servicio invoque eliminar en él, pueda verificar que la eliminación se invoque correctamente en el simulacro. Por lo tanto, está probando la funcionalidad Service.Delete sin probar también el Repository.Delete. – Joseph

1

Sí, ambos.

IMyRepository mock = ...; 
// create Delete(int) expectation 

MyService service = new MyService(mock); 
service.Delete(100); 

// Verify expectations 

Su método Eliminar en este momento solo podría llamar al método Eliminar en el repositorio, pero eso no significa que siempre lo hará. Desea tener pruebas unitarias para esto, en parte, para verificar que se comporte correctamente y en parte como forma de definir sus especificaciones sobre cómo funcionará el repositorio.

También debe tener una prueba que verifique que el constructor arrojará una excepción si el repositorio es nulo. También podría tener otra validación que hacer aquí en este método, como ID no negativos o ID distinto de cero. Tal vez eso no ocurra aquí, hágalo parte de las especificaciones creando pruebas que verifiquen los comportamientos esperados.

Parecen triviales pero puedo garantizar que todo cambiará un día y es posible que no se verifiquen sus expectativas y especificaciones.

+0

Bueno, todo lo que hizo en su ejemplo fue una prueba de Service.Delete(). Se burló de mi repositorio y probó el servicio que en realidad llama al repositorio. –

+0

Lo que quise decir con mi comentario anterior es que dijo "ambos", pero solo escribió el código para probar la capa de servicio. Pero sí, el servicio se prueba en tu caso. –

+0

Lo siento, sí, entonces tendría otro conjunto de pruebas para probar el repositorio concreto, que puede ser más difícil ya que probablemente dependa de bibliotecas de terceros y de otras capas. Esas pruebas pueden terminar siendo más como pruebas de integración. Entonces, ambos, luchan por una cobertura total del código. Pero no creo que pueda descuidar esta clase ya que esta es la abstracción contra la que codificará su aplicación. –

0

Cree la prueba para el Servicio. Actualmente,, todo lo que hace es llamar al método de eliminación de repositorio; sin embargo, no deberías preocuparte por eso. ¿Qué pasa si más tarde sucede algo y la funcionalidad se vuelve mucho más complicada? ¿No desea tener un código de prueba unitaria que le garantice que la funcionalidad sigue funcionando como se esperaba?

Si expone su eliminación a través de su servicio, espera que tenga un efecto. Escribe una prueba unitaria para probar ese efecto. Dependiendo de sus necesidades particulares, diría que es posible que no necesite una prueba en la opción de eliminación del repositorio, especialmente si esa funcionalidad se ejerce como parte de la funcionalidad de supresión del servicio, pero realmente todo depende del nivel de cobertura que tenga. Estoy intentando por.

+0

Pero si pruebo el método Service.Delete() de la unidad, todo lo que puedo hacer es verificar que llame al método Repository.Delete(). No puedo verificar ningún dato, porque la manipulación de datos se realiza en el repositorio. –

+0

¿Es suficiente saber que Service.Delete() llama a Repository.Delete()? Entonces estás bien con solo Service.Delete(). ¿Necesita verificar los datos? Entonces vas a necesitar un cierto nivel de burla para verificar que los datos se modifiquen. –

0

Además, si hubiera creado este código con TDD, se habría realizado una prueba. Realmente importa si las personas pueden llamar a Eliminar a través de su servicio, por lo que en realidad tiene que probarlo.

0

En mi opinión, debe probar ambos. Tal vez puedas crear la clase de contexto de EF de creación en una fábrica separada que pueda probarse más fácilmente y burlar la clase de contexto para las pruebas de MyRepository. Eso será más fácil y usar una fábrica para crear llamadas de contexto me parece silencioso.

+0

Lo haría, pero como puedo googlear en la red, burlarse del contexto de Entity Framework es un dolor en el ... –

Cuestiones relacionadas