¿Cómo hacer pruebas unitarias en un método que tiene en cuenta el tiempo transcurrido?

8

Actualmente estoy en medio de refactorizar un método importante en un sistema heredado. Hubo una prueba casi nula hasta que comencé a trabajar en ella, y agregué bastante para garantizar el trabajo correcto después de mis refactorizaciones.

Ahora me he encontrado con la parte más crucial: el algoritmo que calcula un indicador. Es algo como

indicator = (OneNumberFromA + AnotherNumberFromB) / elapsedTime;

¿Cómo puedo probar el comportamiento correcto para esta función con las pruebas unitarias?

También hay algunos algoritmos ligeramente diferentes en las funciones, que el programa alcanza en algunos casos, pero en todos ellos, elapsedTimees vital para el resultado.

mhr
fuente

Respuestas:

11

De la misma manera que resuelve casi todos los problemas con las pruebas unitarias: se burla del tiempo transcurrido.

Aconsejo usar un método estandarizado para obtener la hora del sistema en todo el sistema y, a continuación, hacer que ese método sea reemplazable, para que sus pruebas unitarias tengan control total. Las pruebas contendrán muchas llamadas ingeniosas como Time.fake(timeA), o incluso Time.stop().

Kilian Foth
fuente
El tiempo se obtiene de hecho a través del sistema. El método de función almacena loginTime y calcula elapsedTime a través de DateTime.Now - loginTime. Trataré de burlarme de eso. Gracias por señalarme en esa dirección.
mhr
55
Luego refactorícelo y reemplace cada llamada a System.currentTimeMillis()con un método Time.now(), que generalmente hace lo mismo, pero en la prueba se puede hacer para devolver cualquier valor que desee. Esto puede requerir cierto esfuerzo, pero no es probable que rompa nada, ya que es un cambio muy centrado y contenido.
Kilian Foth
1

La medición del tiempo y la evaluación del indicador deben estar en diferentes funciones. En su caso, elapsedTimedebe ser una entrada de la función de evaluación. De esa manera, su código de evaluación se puede probar y es más fácil de entender.

Ahora todavía tiene el problema de probar la función de medición de tiempo, pero esto está más allá del alcance de esta pregunta.

Simon Bergot
fuente
Esa es una de las cosas a las que me dirigiré, pero en este momento, elapsedTime se calcula dentro de la función. No estoy seguro de si es bueno extraer esto sin tener una prueba para asegurar que el comportamiento observable permanezca igual, lo que es crucial con respecto a la refactorización de Fowlers .
mhr