Por lo que yo entiendo, la mayoría de la gente parece estar de acuerdo en que los métodos privados no deben probarse directamente, sino a través de los métodos públicos que los llamen. Puedo ver su punto, pero tengo algunos problemas con esto cuando trato de seguir las "Tres leyes de TDD" y utilizo el ciclo "Rojo - verde - refactorizador". Creo que se explica mejor con un ejemplo:
En este momento, necesito un programa que pueda leer un archivo (que contiene datos separados por tabulaciones) y filtrar todas las columnas que contienen datos no numéricos. Supongo que probablemente ya hay algunas herramientas simples disponibles para hacer esto, pero decidí implementarlo desde cero, principalmente porque pensé que podría ser un proyecto agradable y limpio para mí practicar un poco con TDD.
Entonces, primero, "me puse el sombrero rojo", es decir, necesito una prueba que falla. Pensé, necesitaré un método que encuentre todos los campos no numéricos en una línea. Entonces escribo una prueba simple, por supuesto, no se compila de inmediato, así que comienzo a escribir la función en sí, y después de un par de ciclos de ida y vuelta (rojo / verde) tengo una función de trabajo y una prueba completa.
A continuación, continúo con una función, "collectNonNumericColumns" que lee el archivo, una línea a la vez, y llama a mi función "findNonNumericFields" en cada línea para reunir todas las columnas que eventualmente deben eliminarse. Un par de ciclos rojo-verde, y he terminado, una vez más, tengo una función de trabajo y una prueba completa.
Ahora, me imagino que debería refactorizar. Dado que mi método "findNonNumericFields" fue diseñado solo porque pensé que lo necesitaría al implementar "collectNonNumericColumns", me parece razonable permitir que "findNonNumericFields" se vuelva privado. Sin embargo, eso rompería mis primeras pruebas, ya que ya no tendrían acceso al método que estaban probando.
Entonces, termino con métodos privados y un conjunto de pruebas que lo prueban. Dado que tanta gente aconseja que no se prueben los métodos privados, parece que me he arrinconado aquí. ¿Pero dónde fracasé exactamente?
Supongo que podría haber comenzado en un nivel superior, escribiendo una prueba que prueba lo que eventualmente se convertirá en mi método público (es decir, findAndFilterOutAllNonNumericalColumns), pero eso se siente algo contrario al punto completo de TDD (al menos según el tío Bob) : Que debe cambiar constantemente entre escribir pruebas y código de producción, y que en cualquier momento, todas sus pruebas funcionaron en el último minuto más o menos. Porque si empiezo escribiendo una prueba para un método público, habrá varios minutos (u horas, o incluso días en casos muy complejos) antes de obtener todos los detalles en los métodos privados para que la prueba pruebe al público método pasa.
¿Entonces lo que hay que hacer? ¿TDD (con el ciclo rápido de refactorización rojo-verde) simplemente no es compatible con métodos privados? ¿O hay una falla en mi diseño?
private
si tuviera sentido hacerlo.