Programar para el test unitario

Me decido a escribir este post viendo los comentarios del post anterior y porque los test unitarios también es otra cosa en la que tengo interés. También tenemos que ir poniéndolos.

Estoy de acuerdo en que es muy difícil hacer determinados test -e incluso unos pocos bien hechos-, pero también es cierto que hacer el código de cierta forma ayuda a hacerlos.

Por ejemplo, si tengo una clase que instancia una clase de sockets, lee un mensaje de ella, actúa en consecuencia y como resultado envía otro mensaje con, no podré hacer un test fácilmente, salvo que en el test construya el servidor del socket y lo lance. Y quizás no pueda hacerlo, porque el servidor igual debe correr en otro ordenador y no puedo lanzarlo desde mi clase de test en remoto. Sin embargo, si tengo mi clase de socket que implementa una interface y luego se la paso a la clase que quiero, esa clase es más fácil de probar. Desde el test puedo simular la clase de socket con otra hecha a mi medida -creo que se conoce en este mundillo como mock-object- y que implemente la interface. Esta clase simulada de socket puede devolver un mensaje a medida cuando la clase de prueba intente leer y esta clase simulada recibirá los que la clase de prueba intente enviar, por lo que sí puedo comprobar como se comporta la clase sin necesidad de tener el socket abierto.

Para testear la clase de socket, sí puedo instanciar dos sockets en la clase de test de forma que se comuniquen entre ellos. Claro, siempre que la clase de socket sea suficientemente configurable como para indicarle que el servidor es "localhost".

Con base de datos pasa algo parecido. Si la clase consulta o inserta directamente, es difícil probar salvo que tengas la base de datos. Si haces una clase con interface que es la encargada de realizar las inserciones y consultas, es posible pasarle un mock-object de la clase de base de datos a la clase bajo prueba, con lo que se podría hacer alguna prueba sin necesidad de tener la base de datos y teniendo los datos controlados -es el mismo mock-object el que devuelve los datos a nuestra medida o el que recibe lo que la clase bajo prueba intenta insertar.

En fin, no digo que sea fácil y que no requiera trabajo, pero muchas veces el cómo se hace el código ayuda, dificulta e incluso hace imposible el hacer los test.

Esta entrada fue publicada en junit, metodologías. Guarda el enlace permanente.

3 respuestas a Programar para el test unitario

  1. o dijo:

    Tener dificultad para hacer un test unitario a menudo es sintomático de que ese método debería partirse en trozos más pequeños..

    por otra parte, lo de la bd, sockets, etc, si no se dispone de un entorno de desarrollo en el que poder probar-y-desarrollar pues más de lo mismo. Los mock-objects ayudan, pero no son **la** solución a las dificultades para probar probar. Yo los suelo usar más como baterías de datos de pruebas que como simuladores del entorno.

  2. Vallekano dijo:

    Bueno, esa solución que das puede salvarte en algún caso pero yo sigo viendo las pruebas unitarias una cosa muy bonita pero nada práctica, o por lo menos en el 99% de los casos.

    Hablas de crear clases que simulen un comportamiento, pero repito, mi experiencia, me dice que el crear una clase que simule el comportamiento es tanto o más complejo que la clase/metodo que estamos probando.

  3. rfilgueiras dijo:

    Estoy mirando mock objects estos días y la primera impresión que tengo es que el diseño de tu aplicación debe tener unas características muy concretas para que se puedan utilizar los mock objects de forma eficiente y sin que carguen demasiado de trabajo al programador.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.