Sugiero refactorizarlo.
La información que he examinado sugiere que el deseo de probar métodos privados podría ser un olor a código. Algunas personas sugieren que puede ser una señal de que esto se debe refactorizar en una clase separada y hacerse pública.
Ha cubierto las diversas razones a favor y en contra en su propia pregunta, parece estar al tanto de los argumentos. Pero tienes un método que parece bastante complicado e implica una API externa. Eso vale la pena probarlo solo.removeInvalidOperations()
puede seguir siendo un método privado en la clase en la que se encuentra, pero básicamente delegaría en otra dependencia.
class YourClass
{
private OperationRemover remover;
public void addKeywords() {
// whatever
removeInvalidOperations();
}
private void removeInvalidOperations() {
remover.remove();
}
}
Esto le da la ventaja añadida de ser capaz de sustituir esta dependencia en algún momento, incluyendo la posibilidad de poner a prueba su método addKeywords()
sin tener que hacer una llamada de API externa, lo que haría más fácil probar ese método.OperationRemover
podría ser una interfaz, por ejemplo, y para fines de prueba, simplemente debe pasar un talón en su lugar en lugar de la versión concreta utilizada en la producción. En cuanto a su versión concreta, puede escribir pruebas independientemente de lo que esté sucediendo con su clase existente.
Realmente no veo por qué tengo un problema con mi diseño de código actual, sino también no me gusta la idea de la edición de mi código de producción para satisfacer mis necesidades pruebas.
La capacidad de prueba más fácil es una ventaja secundaria. Mírelo de otra manera: lo que en realidad está haciendo es hacer que el código sea poco flexible y extensible. Arriba, hemos separado la llamada a la API externa del código que podría necesitar usar el resultado. La API externa podría cambiar. Puede pasar de un servicio a otro, pero el código que utiliza el resultado no tiene que importarle. Esa clase puede permanecer igual, solo la clase que realmente coloca las llamadas necesita ser modificada (o reemplazada).
Ejemplo del mundo real: El año es 2007 y trabajas para un banco en un gran centro financiero en los Estados Unidos. Su aplicación necesita usar información de cuenta. Su código llega a un servicio web de algún tipo dentro del banco y obtiene la información que necesita, en la forma que necesita, y luego continúa con su procesamiento. En 2008, el sector financiero de Estados Unidos implosiona, y su banco (que está al borde del colapso) es engullido por otro banco. Su aplicación se salva, excepto que ahora tiene que contactarse con una API diferente que ya existe dentro del banco sobreviviente para obtener información de la cuenta desde allí. ¿Debe cambiar el código que consume esta información de cuenta? No necesariamente. Es la misma información de cuenta que antes, solo de una fuente diferente. No, todo lo que necesita cambiar es la implementación que invoca las API. El consumo de código nunca tiene que saberlo.
El hecho de que tal acoplamiento flojo también promueve y facilita las pruebas es una ventaja.
Una solución rápida que he usado a menudo es cambiar el acceso de privado a predeterminado (paquete) y comentar '// acceso de paquete para pruebas unitarias solamente. Si esto es aceptable depende de sus estándares de codificación y de cuánto confíe sus compañeros programadores entienden que este método, incluso si el paquete tiene acceso, no es una "API real". – user949300