¿Modificar visibilidad de propiedad sólo para el test?.

20 views
Skip to first unread message

Pablo Braulio

unread,
Jan 27, 2015, 3:08:29 AM1/27/15
to Lista tdd
Hola.

Quisiera plantear una duda que me ha surgido. A ver si me podéis orientar.

Tengo un código que realiza lo siguiente:

1- Comprueba la existencia de un fichero en disco.
2- Si no existe el fichero, realiza lógicas y construye un array.
3- Escribe un nuevo fichero en disco con el contenido de ese array.

El primer y tercer paso, al ser infraestructura, lo puedo "mockear", pero mi duda es respecto a como testear el resto. Una manera de hacerlo sería comprobando ese array de datos, ya que tendrá un contenido en función de las lógicas. 
Este array es una propiedad privada, podría cambiarle la visibilidad de esta (con un getter, por ejemplo), para poder comprobar su contenido y validad. Pero no me parece muy limpio tener que cambiar la lógica de mi código sólo por el test.

¿Que opinais?.

Saludos y gracias.

Victor Paredes

unread,
Jan 27, 2015, 4:11:44 AM1/27/15
to tdde...@googlegroups.com

Recoda que tdd es una forma de diseñar software, si tenes un metodo privado sin cubrir por un test es por que hiciste algo mal.

Yo creo que en tu caso realizaria la prueba viendo que el archivo se genere correctamente ( saca la logica de generacion a otra clase y mockea ). El array privado es un mero elemento para llegar al objetivo de tener tu archivo generado correctamente.

Es mi humilde opinion.

--
Has recibido este mensaje porque estás suscrito al grupo "TDDev" de Grupos de Google.
Para anular la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a tddev-sp+u...@googlegroups.com.
Para publicar en este grupo, envía un correo electrónico a tdde...@googlegroups.com.
Visita este grupo en http://groups.google.com/group/tddev-sp.
Para acceder a más opciones, visita https://groups.google.com/d/optout.

Pablo Braulio

unread,
Jan 27, 2015, 4:13:38 AM1/27/15
to tdde...@googlegroups.com
¿Te refieres a que compruebe el fichero en el disco?. No me parece
adecuado, en tal caso y puede ser costoso.

El 27/1/15, Victor Paredes <tat...@gmail.com> escribió:
> Para publicar una entrada en este grupo, envía un correo electrónico a
> Para obtener más opciones, visita https://groups.google.com/d/optout.
>


--
Saludos cordiales.
Pablo.

Si lo reenvías, ten la precaución de borrar los datos de procedencia que
encabezarían tu reenvío – empezando por mi dirección de correo
electrónico - . Coloca siempre las direcciones de tus contactos en el
campo <CCO> para que viajen discretas, no en el campo <Para> ni en
el<CC>. De esa forma nadie que lo reciba tendrá constancia de las señas
de los demás destinatarios a los que también se remite. Todo ello a fin
de evitar que nadie se aproveche de todas las direcciones que se van
acumulando al pasar de buzón a buzón para el lanzamiento de correo
basura y otras indeseadas lindezas. Aparte claro está de garantizar la
privacidad.

Pablo Braulio

unread,
Jan 27, 2015, 4:15:52 AM1/27/15
to tdde...@googlegroups.com
Voy a decirlo de otro modo.

En este caso, no me interesa testear que el fichero se está escribiendo, sino su contenido.

Gracias por la contestación.


>> envía un correo electrónico a tddev-sp+unsubscribe@googlegroups.com.

>> Para publicar en este grupo, envía un correo electrónico a
>> tdde...@googlegroups.com.
>> Visita este grupo en http://groups.google.com/group/tddev-sp.
>> Para acceder a más opciones, visita https://groups.google.com/d/optout.
>>
>
> --
> Has recibido este mensaje porque estás suscrito al grupo "TDDev" de Grupos
> de Google.
> Para anular la suscripción a este grupo y dejar de recibir sus mensajes,
> envía un correo electrónico a tddev-sp+unsubscribe@googlegroups.com.

Victor Paredes

unread,
Jan 27, 2015, 4:24:03 AM1/27/15
to tdde...@googlegroups.com

Precisamente esta es la forma de hscerlo.

Clase a: es la que tiene que determinar que va a escribirse en el archivo de texto. ( la que tiene tu array privado )

Clsse b: es la que realiza la escritura del archivo de texto al disco.

Mandas la "clase b" por inyeccion de dependencia y usas un mock para verificar que el archivo va a recibir el contenido que esperas que reciba.

De esta forma mantenes tus clases respetando los principios SOLID y te quedan componentes reutilizables.

Para anular la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a tddev-sp+u...@googlegroups.com.

Vicent Soria

unread,
Jan 27, 2015, 4:24:40 AM1/27/15
to tdde...@googlegroups.com
Hola,

En el caso que planteas, parece que tienes un código que hace demasiadas cosas. Recuerda: SRP.
Cómo lo plantearía yo es:

Tienes un objeto que es capaz de escribir a un fichero (una especie de wrapper).
Por otra parte, tienes otro objeto que construye el contenido del array y lo devuelve.
Y en última instancia, otro objecto que usa los dos colaboradores para realizar el proceso a más alto nivel.

De esta manera, puedes testear unitariamente el 2º y el 3º (en éste último deberías mockear los otros 2).
El primer objeto, yo lo testearía de manera más funcional, seguramente con un acceso real a disco.

Espero que te sirva de algo.
Saludos.

Vicent Soria

Pablo Braulio

unread,
Jan 27, 2015, 6:41:15 AM1/27/15
to tdde...@googlegroups.com
Realmente SRP lo he respetado.

El ejemplo que he puesto es un resumen, realmente está todo dividido
en clases con reponsabilidad simple.

El 27/1/15, Vicent Soria <vicent...@gmail.com> escribió:
> Hola,
>
> En el caso que planteas, parece que tienes un código que hace demasiadas
> cosas. Recuerda: SRP
> <http://es.wikipedia.org/wiki/Single_responsibility_principle>.

Juan José Montes de Oca Arbós

unread,
Jan 27, 2015, 6:48:30 AM1/27/15
to tdde...@googlegroups.com
Hola Pablo, para mi no tiene sentido cambiar la implementación de privado a público solamente para poder testear algo.

NOTA: Si tenés algo privado que es necesario testear (ya sea porque tiene un cálculo complejo o el motivo que consideres necesario), habría que analizar en primer lugar porque es privado, quizás eso sea incorrecto.

Sin conocer bien lo que necesitás, y basandome en supuestos, se me ocurre que no es necesario testear el array, sino, el resultado que genera de salida esa clase que, internamente, administra los datos con un array.

Saludos Y ÉXITOS!!!



--
Juan José Montes de Oca Arbós.

===========================
Web personal: http://juanjose.montesdeocaarbos.com.ar/blog/

Angel Java Lopez

unread,
Jan 27, 2015, 6:53:53 AM1/27/15
to tdde...@googlegroups.com
Hola gente!

No entendi del todo la situacion a testear, pero algun comentario: no se en que lenguaje es el codigo, pero yo en Java y en C# usuria streams, en lugar de ficheros, y entonces la prueba la hago pasando a la clase B (la que tiene que escribir) un stream en memoria, y luego compruebo el contenido. Si eso funciona bien, y hace falta, en algun test a la Clase B se le pasa un stream de un archivo abierto, y luego se comprueba el contenido del archivo (seguramente, en mi caso, eso surgiria de otro test de otro caso mas complejo, el test inicial esta cubierto con la prueba de pasar un stream)

Es raro que haga codigo "que va SOLO contra archivo". En general, va contra streams, o hago codigo que genera lo que hay que generar (por ejemplo, un .compile que genera texto con el programa compilado) y luego lo escribo en lo que sea (un archivo, un stream, la consola, un socket, etc)

Nos leemos!

Angel "Java" Lopez
@ajlopez

Antonio Martinez

unread,
Jan 27, 2015, 7:18:17 AM1/27/15
to tdde...@googlegroups.com
Opino que si la función es privada no debes testearla.

Las funciones privadas a mi me salen (tanto usando TDD como sin usarlo) cuando refactorizo para eliminar código duplicado o para una mejor expresión de los métodos publicos. Lo que yo testeo son interfaces que por definición son públicas. además eso permite probar comportamiento y no implementación. Si una función/método es privado no va a ser llamado por ningún elemento externo a la clase porque lo que no conlleva comportamiento.

Yo haría un test de la función pública que llama a ese método privado. Si esa función pública llama a muchas privadas, quizás estás violando SRP (en la interfaz o en la función pública). 

Resumiendo:
  • No hagas test de funciones privadas.
  • Haz test de las interfaces (comportamiento) y no de las funciones (implementación)

Carlos Peix

unread,
Jan 27, 2015, 7:44:42 AM1/27/15
to tdde...@googlegroups.com
Desde el punto de vista de testing (es decir, descartando por ahora TDD), es importante entender que querés testear. En tiendo que en este caso es la lógica que, a partir de que no existe el archivo, genera un array con cierto contenido y que luego genera el archivo con ese contenido.

Queda fuera que el archivo efectivamente termine en el disco y que funcione la verificación de que exista ese archivo.

Tal como dijeron otros, te conviene hacer un objeto que tenga la responsabilidad de almacenar archivos, recuperarlos y verificar si existen en el almacenamiento (incluso, podrías elevar el nivel de abstracción, hoy es disco pero podría ser cualquier otro, como base de datos, big tables, etc.).

Me imagino un test-doulble de este tipo (C#), está específicamente diseñado para este test y para simplificar la idea:

public class TestFileAccessor : IFileAccessor {

    public string SavedContent;

    public bool Exists(string fileName) {
        return false;
    }
    public void Exists(string fileName, string content) {
        this.SavedContent = content;
    }
}

Donde la propiedad SavedContent es publica y no esta en la interfaz IFileAccessor, es decir, es específica del test-double y es la propiedad publica que necesitas para verificar.

Todo este razonamiento es mas o menos el mismo en el caso de estar con TDD, solo que en lugar de "la lógica que deseas probar" sería "el comportamiento que deseas conseguir".

Un saludo

----------------------------------
Carlos Peix

--
Reply all
Reply to author
Forward
0 new messages