Pregunta

Necesito desarrollar un algoritmo bastante simple, pero estoy confundido tipode como la mejor manera de escribir una prueba para ello.

Descripción general: las necesidades de los usuarios sean capaces de eliminar un plan. Plan tiene tareas asociadas con ella, estos deben ser eliminados, así (siempre y cuando ellos no lo ha hecho).

Pseudo-código como la forma en que el algoritmo debe comportarse:

   PlanController.DeletePlan(plan)
     =>
     PlanDbRepository.DeletePlan()
      ForEach Task t in plan.Tasks
          If t.Status = Status.Open Then
            TaskDbRepository.DeleteTask(t)
          End If
      End ForEach

Ahora por lo que tengo entendido, se supone que las pruebas unitarias no tocar la base de datos o generalmente requieren el acceso a cualquiera de los sistemas externos, así que supongo que tengo dos opciones:

1) Mock a cabo las llamadas del repositorio, y comprobar si han sido llamados el número apropiado de veces como afirma

2) Crear recibos para ambas clases de repositorios, el establecimiento de su bandera de borrar manualmente y compruebe que los objetos adecuados han sido marcados para su eliminación.

En ambos enfoques, la gran pregunta es: ¿Qué es exactamente estoy probando aquí? ¿Cuál es el valor añadido de que tales pruebas me darían?

Cualquier penetración en este sería muy apreciada. Esta técnica no está vinculado a ningún marco de pruebas de unidad específica, aunque tenemos RhinoMocks a utilizar. Pero yo preferiría una explicación general, de modo que pueda ajustar adecuadamente la cabeza alrededor de esto.

¿Fue útil?

Solución

se burle el repositorio y luego construir un plan ficticio en su unidad de prueba que contiene tanto abiertas como cerradas tareas. A continuación, llame al método actual que pasa este plan y al final verificar que el método DeleteTask fue llamado con argumentos correctos (tareas sólo con el estado = abierto). De esta manera se aseguraría que sólo tareas abiertas asociadas a este plan ha sido borrado por el método. También no se olvide (probablemente en una prueba de unidad por separado) para verificar que el plan en sí mismo ha sido eliminado mediante la afirmación de que el método DeletePlan ha sido llamado en el objeto de su están pasando.

Otros consejos

Para añadir a la respuesta de Darin me gustaría decir lo que en realidad se está probando. Hay un poco de lógica de negocio en ese país, por ejemplo, el control sobre la situación.

Esta prueba unitaria que podría parecer un derecho muda poco ahora, pero ¿qué pasa con los futuros cambios en el código y el modelo? Esta prueba es necesaria para asegurarse de que esta funcionalidad aparentemente simple siempre será seguir trabajando.

Como se anotó, que está probando que la lógica de los algoritmos se comporta como se esperaba. Su enfoque es correcto, pero hay que considerar el futuro - meses en el camino, puede necesitar ser cambiado este algoritmo, un desarrollador diferente chuletas se rehace y que, falta una pieza fundamental de la lógica. Las pruebas unitarias ahora se producirá un error, y el desarrollador se le avisará a su error. Prueba de la unidad es útil en la salida, y semanas / meses / años en el camino también.

Si desea agregar más, tenga en cuenta cómo se maneja el fracaso. Tiene su base de datos Mock una excepción en el comando de eliminación, prueba que sus manijas del algoritmo esto correctamente.

El valor adicional proporcionada por las pruebas es comprobar que el código hace lo correcto (en este caso, eliminar el plan, elimine las tareas abiertas asociados con el plan y dejar las tareas cerrados asociados con el plan).

Suponiendo que haya pruebas en el lugar para sus clases de repositorios (es decir, lo que hacen las cosas bien cuando se elimina está llamado en ellos), entonces todo lo que necesita hacer es comprobar que los métodos de eliminación se llaman adecuadamente.

Algunas de las pruebas que usted podría escribir son:
Cómo borrar un plan de vacío solamente llamar DeletePlan?
Hace borrar un plan con dos tareas abiertas llaman DeleteTask para ambas tareas?
¿Tiene la eliminación de un plan con dos tareas cerradas no llama DeleteTask en absoluto?
No la eliminación de un plan con uno abierto y uno cerrado DeleteTask llamada tarea una vez en la tarea correcta?

Editar:. Yo usaría la respuesta de Darin como el camino a seguir de él sin embargo

Interesante, me parece prueba de la unidad ayuda a enfocar la mente en las especificaciones. A tal fin permítame hacerle esta pregunta ...

Si tengo un plan con 3 tareas:

Plan1 {
 Task1: completed
 Task2: todo
 Task3: todo
}

y llamo de borrar en ellos, lo que debería ocurrir la que el Plan?

Plan1 : ?
Task1: not deleted
Task2: deleted
Task3: deleted

Se Plan1 eliminada, dejando huérfanos Task1? o se trata de otro modo marcado como eliminado?.

Esta es una gran parte del valor que veo en las pruebas unitarias (A pesar de que es sólo 1 de los 4 valores: 1) Spec 2) Comentarios 3) Regresión 4) granularidad

En cuanto a la manera de prueba, yo no sugieren burla de todos. Yo consideraría un método 2 parte La primera se vería así

public void DeletePlan(Plan p)
{ 
  var objectsToDelete = GetDeletedPlanObjects(p);
  DeleteObjects(objectsToDelete);
} 

Y yo no probar este método. Me gustaría probar las GetDeletedPlanObjects método, que no tocaría la base de datos de todos modos, y me permitirá enviar en escenarios como la situación anterior .... lo que lo haría entonces afirmar con www.approvaltests.com, pero eso es otra historia: - )

Pruebas feliz, Llewellyn

No escribiría pruebas unitarias para esto porque para mí esto no es la prueba de comportamiento, sino más bien la aplicación. Si en algún momento desea posibilidad de que el comportamiento que no elimina las tareas sino que los pone a un estado de 'discapacitados' o 'ignorado', las pruebas unitarias se producirá un error. Si prueba todos los controladores de esta manera las pruebas unitarias son muy frágiles y necesitan ser cambiados con frecuencia.

Refactor a cabo la lógica de negocio a un 'TaskRemovalStrategy' si quieres probar la lógica de negocio para este y dejar los detalles de implementación de la extracción hasta la propia clase.

OMI puede escribir sus pruebas de unidad en torno a la PlanRepository abstracto y las mismas pruebas debe ser útil para probar la integridad de los datos en la base de datos también.

Por ejemplo, podría escribir una prueba -

void DeletePlanTest()
{
    PlanRepository repo = new PlanDbRepository("connection string");
    repo.CreateNewPlan(); // create plan and populate with tasks
    AssertIsTrue(repo.Plan.OpenTasks.Count == 2); // check tasks are in open state
    repo.DeletePlan();
    AssertIsTrue(repo.Plan.OpenTasks.Count == 0);
}

Esta prueba funcionará incluso si su repositorio elimina el plan y su base de datos elimina las tareas relacionadas a través de un desencadenador de eliminación en cascada.

El valor de dicha prueba es si la prueba se realiza para PlanDbRepository o una MockRepository todavía se compruebe que el comportamiento es correcto. Así que cuando se cambia cualquier repositorio de código o incluso su esquema de base, puede ejecutar las pruebas para comprobar no hay nada roto.

Se puede crear este tipo de pruebas que cubren todos los posibles comportamientos de su repositorio y luego usarlos para asegurarse de que ninguna de sus cambios no se rompen la aplicación.

También puede parametrizar esta prueba con una instancia del repositorio concreto y los reutilice la prueba de cualquier implementaciones futuras de los repositorios.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top