Tengo un objeto de servicio no trivial desarrollado con TDD. Comenzó con una tarea simple: para un objeto de la cola, construya un intento de procesamiento asíncrono. Así que escribí una prueba alrededor de mi método constructAttempt()
:TDD - ¿Refactorizar en caja negra?
void constructAttempt() {...}
Hay numerosos escenarios posibles que deben tenerse en cuenta, así que tengo una docena de pruebas para este método.
Luego implementé lo que realmente necesitaba: Escanear toda la cola y construir un lote de intentos. Así que el código se parece más a:
public void go() {
for (QueuedItem item : getQueuedItems()) {
constructAttempt(item);
}
}
por lo que añade una nueva prueba o dos para este método go()
.
Finalmente descubrí que necesitaba un poco de pre-procesamiento que a veces puede afectar constructAttempt()
. Ahora el código se parece más a:
public void go() {
preprocess();
for (QueuedItem item : getQueuedItems()) {
constructAttempt(item);
}
}
Tengo algunas dudas sobre lo que debería hacer ahora.
¿Debo mantener el código como está, con constructAttempt()
, preprocess()
y go()
probado independientemente? ¿Por qué sí/por qué no? Me arriesgo a no cubrir los efectos secundarios del preprocesamiento y romper la encapsulación.
¿O debo refactorizar todo mi conjunto de pruebas para que solo llame al go()
(que es el único método público)? ¿Por qué sí/por qué no? Esto haría las pruebas un poco más oscuras, pero por otro lado tomaría todas las interacciones posibles en consideración. De hecho, se convertiría en una prueba de recuadro negro utilizando solo la API pública, lo que puede no estar en línea con TDD.
Si refactoriza su conjunto de pruebas para probar solo el método go() ... ¿cómo identificará si los errores detectados están en preprocess() o buildAttempt? –