2009-03-09 14 views
9

Me gustaría probar un método en una clase que he hecho, pero este método requiere que se llame primero a otro método. Ejemplo:Pruebas unitarias de métodos dependientes

// This would work 
MyClass myClass1 = new MyClass(mockDevice); 
myClass1.Run(myDatastructure); 
myClass1.Stop(); 

// This would throw an InvalidOperationException 
MyClass myClass2 = new MyClass(mockDevice); 
myClass2.Stop(); 

Run está comenzando una operación en un dispositivo de hardware, y Stop es, por supuesto, tratar de detener esa operación (enviando un restablecimiento mando e iniciar un tiempo de espera del temporizador).

De todos modos me gustaría probar varios post-condiciones de llamar Stop, pero me gustaría no tener que llamar Run, porque yo estoy probando Stop - no Run! Me gustaría algo como esto:

MyClass myClass = new MyClass(mockDevice); 
myClass.Stop(); 
Assert.IsTrue(mockDevice.ResetCalled); 

Hasta ahora sólo ver una posible solución, y que consiste en crear una TestableMyClass que hereda de MyClass, que hace que sea posible establecer el estado interno derecha de la MyClass instancia ante llamando al Stop. El problema con esta solución es que tengo que cambiar mi MyClass -implementación para tener miembros protegidos en lugar de miembros privados, y I no como la idea de tener que cambiar la implementación para poder probarla.

Debo usar esta solución, ¿hay algún error en mi diseño o hay una forma más inteligente de hacerlo?

Respuesta

6

Hasta donde yo lo veo, ya está probando Stop de las dos maneras en que se puede utilizar (con y sin una operación en ejecución). Siempre y cuando el mockDevice esté haciendo su trabajo, me parece que lo está probando razonablemente. Lo ideal sería que pudieras verificar los comandos enviados al dispositivo, etc. (lo que la mayoría de los frameworks simulados harán simple).

+0

¿Entonces crees que está bien simplemente llamar a Run, Stop, Assert? – toxvaerd

+0

Sí, eso creo. Y también vale la pena llamar a Stop without Run para comprobar que se ha lanzado la excepción requerida. En última instancia, no es válido llamar primero a Stop without Run ... –

4

En esta situación, personalmente, me gustaría tener dos pruebas para esto:

  1. Prueba sin Run() se llama en primer lugar. Yo probaría si realmente arroja la excepción. También probaría si las condiciones de publicación son las que espero que sean.
  2. Prueba con ejecutar() se llama primero. Solo probaría las condiciones de publicación, eso espero.

Esos son los dos únicos usos importantes del método que tienen comportamientos diferentes, por lo tanto los probaría a ambos.

EDIT: entiendo, ¿por qué usted no desea llamar plazo, antes del paro - usted piensa que si falla la ejecución de las obras, que se supone que es único método de prueba de parada muy probablemente fallará también.

Sin embargo, supongo que también tiene una prueba para el método de ejecución. Esto significa, que cuando las pruebas, que prueban el comportamiento de las pruebas del método run-stop-method deben pasar también. Si las pruebas del método de ejecución fallan, los resultados de las pruebas del método de ejecución no están definidos, pueden fallar o no.

Entonces, yo diría que no tema llamar a otros métodos dependientes en sus pruebas, pero asegúrese de probar esos métodos dependientes en pruebas separadas.

+0

¡Ya estoy probando el método Stop que arroja una excepción, pero veo tu punto! – toxvaerd

+1

Gracias por su respuesta, pero voy a aceptar la respuesta de Marc Gravell, ya que fue el primero :-) – toxvaerd

1

No ayudará a su problema inmediato, pero tiendo a favorecer el mapeo de estado a tipo en lugar de tener objetos con diferentes modos.

IdleDevice idle = new IdleDevice(mockDevice); 
RunningDevice running = idle.Run(myDatastructure); 
running.Stop(); 

// This would not compile, as IdleDevice has no Stop method 
IdleDevice idle = new IdleDevice(mockDevice); 
idle.Stop(); 

Si no puede compilar situaciones imposibles, no necesita probarlas.

+0

¡Me gusta ese diseño! Consideraré usar eso, pero por ahora solo probaré Stop seguido por Run. Gracias – toxvaerd