Hace poco hicimos un post sobre como ejecutar Mockito junto a JUnit 5 en eclipse. Hoy veremos un poco más acerca del tema.
Más concretamente veremos un par de nuevas características: Como mockear un atributo estático y la creación de un objeto de forma interna. Ambas cosas ya se podían realizar con otra librería de testing como Powermock, como puedes ver aquí. Pero esta librería aún no es compatible con JUnit 5.
Para empezar con el desarrollo de las pruebas, vamos a utilizar la versión de mockito-inline en vez de directamente mockito-core. Esta versión de la librería nos permitirá dos cosas:
- Ahorrarnos la anotación @ExtendWith(MockitoExtension.class)
- Evitar errores con las nuevas funcionalidades. Del tipo: The used MockMaker SubclassByteBuddyMockMaker does not support the creation of static mocks.
- Sin parámetros:
@Test public void info() { assertThat("Calculator v 1.0", equalTo(Calculator.info())); try (MockedStatic<Calculator> mocked = mockStatic(Calculator.class)) { mocked.when(Calculator::info).thenReturn("Calculator mocked"); assertThat("Calculator mocked", equalTo(Calculator.info())); mocked.verify(Calculator::info); } assertThat("Calculator v 1.0", equalTo(Calculator.info())); }
- Con parámetros:
@Test public void sum() { assertThat(5, equalTo(Calculator.sum(2, 3))); try (MockedStatic<Calculator> mocked = mockStatic(Calculator.class)) { mocked.when(() -> Calculator.sum(2, 3)).thenReturn(6); assertThat(6, equalTo(Calculator.sum(2, 3))); mocked.verify(() -> Calculator.sum(2, 3)); } assertThat(5, equalTo(Calculator.sum(2, 3))); }
En ambos ejemplos se puede ver cual es el comportamiento del método estático antes y después de su simulación. Y como podemos mockearlo dentro del try/catch gracias a MockedStatic.
Recordar que para poder ejecutar estos test a través de Maven es necesario tener una versión superior del maven-surefire-plugin a 2.2.
Ahora veremos como emular la creación de objetos dentro de métodos que queremos probar. Esta característica esta disponible desde la versión 3.5.0.
Tenemos una clase que dentro de un método crea un objeto que luego es usado. Como puede ser este ejemplo:
public class BookService { private BookDao dao; public Book getById(final int i) { dao = new BookDao(); return dao.getById(i); } }
Es posible que no siempre tengamos el código o la configuración disponible para utilizar ese objeto que se construye dentro de nuestro método, y debido a ello debemos emularlo. A través de MockedConstruction podremos emular la creación de una clase concreta y además modificar su comportamiento.
En este caso tendremos que definir el funcionamiento de la clase que será instanciada en la misma invocación del método mockConstruction. Y realizar las pruebas pertinentes dentro del ámbito de ese try/catch.
@Test public void getById() { assertThat("Ender's Game", equalTo(new BookService().getById(1).getName())); try (MockedConstruction<BookDao> mdu = Mockito.mockConstruction(BookDao.class, (mockdao, context) -> { Book b = new Book(1, "The stars my destination", "Alfred Bester"); when(mockdao.getById(1)).thenReturn(b); })) { BookService service = new BookService(); assertThat("The stars my destination", equalTo(service.getById(1).getName())); } assertThat("Ender's Game", equalTo(new BookService().getById(1).getName())); }
Si queremos emular más de una construcción deberemos duplicar y anidar la creación de esos constructores y sus ámbitos try/catch.
Con estas dos nuevas características de Mockito solventamos un par de las mayores dificultades a la hora de hacer pruebas de lógica compleja. Y sin necesidad de más frameworks de testing o lógica compleja.
No hay comentarios:
Publicar un comentario