EasyMock

De Dos Ideas.
Revisión del 19:55 10 may 2009 de 200.106.34.172 (discusión) (El escenario)
Saltar a: navegación, buscar

EasyMock proporciona Mock Object para interfaces durante la Prueba Unitaria mediante la generación de estas sobre la marcha utilizando mecanismo de Proxy de Java. Debido al estilo único de registro de espectativas en EasyMock, la mayoría de Refactor's no afectará a los objetos Mock. Así EasyMock es perfecto para Test Driven Development.

EasyMock es software de código abierto disponible bajo los términos de la licencia MIT.

Ejemplo

El escenario

Supongamos la siguiente interfaz de negocio:

public interface PlanInvasionBo {
    public InvasorDto findInvasorById(Long id);
}

Tenemos así la clase PlanInvasionBoImpl que la implementa. Esta clase se comunica con un DAO para realizar la búsqueda del objeto de dominio Invasor. Después de obtenerlo, lo convierte a un InvasorDto y lo devuelve.

El Dao en cuestión es de la forma:

public interface PlanInvasionDao {
    public Invasor findInvasorById(Long id);
}

Usamos Spring Framework para inyectar la dependencia que tiene nuestro InvasorBoImpl con el Dao.

Asi, nuestra clase InvasorBoImpl queda bastante simple: public class PlanInvasionBoImpl implements PlanInvasionBo {

    private PlanInvasionDao planInvasionDao;
    public InvasorDto findInvasorById(Long id) {
        Invasor invasor = planInvasionDao.findInvasorById(id);
        InvasorDto invasorDto = new InvasorDto(invasor.getId(), invasor.getNombre());
        return invasorDto;
    }
    //Getters y setters de planInvasioDao a continuacion...

}

Creando el test de PlanInvasioBoImpl

Crearemos entonces un test unitario usando JUnit para nuestro método PlanInvasioBoImpl.findInvasioById().

Obviamente, no queremos testear a nuestro Dao (recordemos la definición de Prueba Unitaria!), así que deberemos crear un Mock Object para simularlo.

La creación de mocks es muy simple con EasyMock. Los pasos básicos son:

  1. Crear el mock (usualmente, en el setUp() del test
  2. "Grabarle" el comportamiento esperado
  3. Iniciar el mock (a través del método replay())
  4. Ejecutar nuestro método a testear
  5. Verificar el mock (a través del método verify())
  6. Realizar otros assert nuestros

Así, nuestro test completo quedaría:

package test.com.dosideas.mock.business.impl;
//imports varios...
import static org.easymock.EasyMock.*;
public class PlanInvasionBoImplTest extends TestCase {
    private PlanInvasionBoImpl planInvasionBo;
    private PlanInvasionDao mockDao;
    protected void setUp() throws Exception {
        mockDao = createMock(PlanInvasionDao.class);
        planInvasionBo = new PlanInvasionBoImpl();
        planInvasionBo.setPlanInvasionDao(mockDao);
    }
    public void testFindInvasorById() {
        Long id = 1L;
        Invasor invasor = new Invasor(id, "Zim");
        expect(mockDao.findInvasorById(id)).andReturn(invasor);
        replay(mockDao);
        InvasorDto resultado = planInvasionBo.findInvasorById(id);
        verify(mockDao);
        assertEquals(invasor.getId(), resultado.getId());
        assertEquals(invasor.getNombre(), resultado.getNombre());
    }
}

Y lo que ocurre es lo siguiente...

Como vemos, realizamos un import static de varios métodos de la clase EasyMock (si, necesitamos JSE 5 para la última versión de EasyMock)

En el método setUp() creamos el mock. Los mocks se crean a partir de interfaces. Así, le asignamos la dependencia a nuestro Bo a testear.

Finalmente, ya en testFindInvasionById() y antes de ejecutar el método a testear, grabamos el comportamiento que deseamos de nuestro mock. La línea "expect(....)" puede leerse como:

"Esperar que se invoque a mockDao.findInvasorById() con el parámetro id, y entonces devolver invasor".

Por último, la llamada a "verify" verifica que se las invocaciones a nuestro mock hayan ocurrido, en el orden que dijimos.

EasyMock 2.4

  • Se agregaron los métodos resetToNice/Default/Strict
  • Se hicieron más flexibles los cmoparadores genéricos
  • Los mocks son serializables
  • Se pueden crear mocks thread-safe

Ver también