Pruebas unitarias usando mock objects

Hoy comenzaré el día escribiendo un post después de casi dos meses lejos del blog, ha sido un tiempo largo pero ha sido aprovechado para aprender nuevas tecnologías e historias que compartir por aquí.

El tema de hoy será como escribir pruebas unitarias usando mock objects, pero, ¿qué son los mock objects? Yo los definiría como objetos programables para que se comporten de una manera determinada en runtime. ¿Y para qué puede servirnos esto al hacer pruebas unitarias? Nos servirá para probar las clases aisladas de sus dependencias, así, si una de las clases de las que nuestra clase depende falla, entonces este error no afectará la prueba unitaria de nuestra clase y deberemos identificar y solucionar ese problema en la otra clase (que debería tener escritas algunas pruebas unitarias).

Veamos un ejemplo en el que las depedencias pueden fallar.

Clases con dependencias La clase que queremos probar es ManejoDeUsuariosImpl, una implementación de la interface ManejoDeUsuarios, ésta clase se compone de instancias de LDAPAccesibleImpl, esto significa que si algo falla en LDAPAccesibleImpl nuestra clase también fallará probablemente y al hacer pruebas unitarias lo que queremos es someter a prueba exclusivamente el comportamiento de una clase independientemente del correcto funcionamiento de sus dependencias. Para darnos una mejor idea… ¿Qué podría fallar en LDAPAccesibleImpl? Hmm creo que todo, podría fallar la conexión de red al servidor LDAP, podría suceder que hayan eliminado al usuario que pensabamos usar para nuestras pruebas unitarias, etc.

Bueno, veamos un ejemplo de prueba unitaria para nuestra clase ManejoDeUsuariosImpl que es la implementación de ManejoDeUsuarios.

ManejoDeUsuarioImplTest.java

package com.imageneureka;

import org.junit.Test;

import static org.easymock.EasyMock.*;

public class ManejoDeUsuariosImplTest {

 private static final String USUARIO_ACTIVO = "active";
 private static final String USUARIO_NO_EXISTENTE = "inactive";

 @Test
 public void hacerAlgoConUnUsuarioActivoTestHappyPath()
 throws Exception {
 // primer paso: creamos el mock, usando el metodo
 //estatico org.easymock.EasyMock.createMock
 LDAPAccesible foo = createMock(LDAPAccesible.class);
 // segundo paso: establecemos el comportamiento
 //, parametros -> respuesta
 expect(foo.esUnUsuarioActivo(USUARIO_ACTIVO)).
 andReturn(Boolean.TRUE).anyTimes();
 // invocamos replay sobre el mock
 replay(foo);
 ManejoDeUsuariosImpl bar = new ManejoDeUsuariosImpl();
 // necesitamos esta linea para establecer la instancia
 //de LDAPAccesible que usara
 // nuestra clase a probar, en este caso el mock
 bar.setMyLDAPAccesibleImpl(foo);
 bar.hacerAlgoConUnUsuarioActivo(USUARIO_ACTIVO);
 // invocamos verify sobre el mock
 verify(foo);
 }

 @Test(expected=IllegalArgumentException.class)
 public void hacerAlgoConUnUsuarioActivoTestLLamadaIncorrecta()
 throws Exception {
 // primer paso: creamos el mock, usando el metodo estatico
 //.easymock.EasyMock.createMock
 LDAPAccesible foo = createMock(LDAPAccesible.class);
 // segundo paso: establecemos el comportamiento,
 //parametros -> respuesta
 expect(foo.esUnUsuarioActivo(USUARIO_NO_EXISTENTE)).
 andReturn(Boolean.FALSE).anyTimes();
 // invocamos replay sobre el mock
 replay(foo);
 ManejoDeUsuariosImpl bar = new ManejoDeUsuariosImpl();
 // necesitamos esta linea para establecer la instancia
 //de LDAPAccesible que usara
 // nuestra clase a probar, en este caso el mock
 bar.setMyLDAPAccesibleImpl(foo);
 bar.hacerAlgoConUnUsuarioActivo(USUARIO_NO_EXISTENTE);
 // invocamos verify sobre el mock
 verify(foo);
 }
}

Antes de que revisemos el ejemplo les sugiero bajarse el ejemplo completo para que puedan ver la dependencia entre las clases de implementacion y asi puedan darse una idea mas clara de qué es lo que pretende testear esta prueba unitaria.

http://www.4shared.com/file/XfzNNqwc/easyMockTest.html

En el archivo que bajarán encontrarán una carpeta con un archivo pom.xml, éste es el project object model de maven, para los que no conocen maven, es un manejador de dependencias y proyectos muy útil, con él solamente necesitan el pom.xml y las dependencias (jars) se bajan de internet automáticamente, además ya se está convirtiendo en el estándar para gestionar proyectos, por lo tanto: http://www.chuidiang.com/java/herramientas/maven.php además tiene muy buena integración con los IDEs que conozco, a saber Netbeans y Eclipse, en Netbeans tan solo tiene que ir a instalar plugins seleccionar el plugin para maven y ya esta, listo para usar.

Regresando a los nuestro, en esta prueba unitaria hay dos métodos de prueba, uno de ellos (hacerAlgoConUnUsuarioActivoTestHappyPath() ) prueba la clase bajo circuntancias favorables (usuario válido) y el otro (hacerAlgoConUnUsuarioActivoTestLLamadaIncorrecta()) prueba la llamada al método ManejoDeUsuariosImpl.hacerAlgoConUnUsuarioActivo() con un usuario incorrecto, circunstancia bajo la cual éste metodo debería responder con una excepción IllegalArgumentException y el proceso de emulación del comportamiento de la dependencia de la clase a testear se detalla como comentarios en el ejemplo.

Por último, cabe mencionar que easyMock no es el único framework para crear mock objects, también existe JMock, el cual implementa ésta funcionalidad aunque con un estilo DSL

3 thoughts on “Pruebas unitarias usando mock objects”

  1. Hola, estoy leyendo tu artículo “Pruebas unitarias usando mock objects” pero no anda el link con el código fuente. Podrías enviármelo a mi correo?
    Estoy necesitando entender el uso de EasyMock y soy un poco novato en Java.
    Saludos!

Leave a Reply

Your email address will not be published. Required fields are marked *