Dobles de test con jMock en un ejemplo

Introducción

En los dos últimos artículos (este y este) hemos visto cómo crear nuestros propios dobles de test. En este artículo vamos a ver un ejemplo de una librería de dobles de test: jMock.

jMock

Hay muchas librerías de dobles de test, como easyMock, Mockito y JMockit. La mayoría de esta librerías están bien y te van a ayudar a crear dobles de test que te faciliten el trabajo de testear una clase.

Yo utilizo jMock porque me ayuda a mejorar el diseño de mi código. Por defecto, nos obliga a tener que declarar de forma explícita cuales son las llamadas que todos los dobles de test que utilicemos en nuestro código a probar.
Si, por ejemplo, en un método tenemos un doble de test que llamamos a tres de sus métodos, tenemos que especificar que permitimos la ejecución de los tres métodos.

Al tener que añadir todas las llamadas al principio del test, podemos ver si hay algo que huele mal (smell) en nuestro código, y así poder mejorar nuestro diseño.

Un inconveniente de jMock comparado con otras librerías como easyMock es que es más complicado de leer el código, pero personalmente es más que suficientemente legible el código.

Ejemplo

En el artículo sobre dobles de test de tipo spies, hay un ejemplo con dos tipos de dobles: spies y stub. Vamos a utilizar ese mismo ejemplo, junto con el mismo código de producción pero añadiendo un test utilizando jMock. Al tener un test con dobles de test hecho por nosotros y otro test con dobles de test de jMock nos va a permitir el ver la diferencia de utilizar la librería y nuestro código.

Vamos a utilizar el mismo código de producción y añadiremos al código de test un nuevo test utilizando jMock.

Creo que el código de producción que aparece arriba es fácil de entender, pero si necesitas alguna explicación extra, en el artículo sobre spies puedes encontrarla.
A continuación, el código de test.

Ambos test hacen lo mismo, comprueban que UserService.findOrCreateWith llama al método sendEmailTo de EmailService, o lo que es lo mismo, comprueban que se envía un email.
La mayor diferencia entre ambos test es que el primero falla cuando nuestro doble de test devuelve false y que el segundo falla lanzando una excepción.

El test con nuestro código de dobles de test comprueba de forma explícita que es llamado el método. Y el test con los dobles de test con jMock comprueba de forma implícita que es llamado el método.

El test should_send_an_email_when_a_user_was_created_with_jmock, dentro de Expectations comprueba que es llamado un vez el método EmailService.sendEmailTo en:

Nuestro doble de test también podría lanzar una excepción cuando no es llamado el método, pero para ello tendríamos que crear un método que realizara la comprobación y lanzara la excepción. Este método debería de utilizarse al final del test.
jMock no necesita que llamemos a ningún método para comprobar las llamadas a los colaboradores porque siempre comprueba internamente (gracias a la anotación Rule) al final de cada test si las expectativas de cada doble de test fueron satisfechas.

Dobles de test propios o librería

Cuando descubrí los dobles de test, los creaba todos a mano, pero ahorré mucho tiempo cuando empecé a utilizar librerías.
Actualmente la mayoría de mis dobles de test los creo con jMock.

Aunque utilizo mas jMock que mis propios dobles de test, siempre hay casos en los que resulta mucho más fácil el crear mis propios dobles de test.
Por ejemplo, cuando resulta complicado el añadir un doble de test con jMock siempre utilizo mis propios dobles de test.
Otra ejemplo sería, cuando no voy a utilizar para nada en los test un colaborador creo un doble de test de tipo dummy o stub para que sea más fácil de entender el test.