miércoles, 3 de enero de 2018

JUnit 5: Nuevas caracteristicas - 2

Ya hicimos un post sobre JUnit 5 y en este seguiremos avanzando sobre las posibilidades de la nueva versión. Algo más avanzadas que en el anterior.
Ahora podemos pasar parámetros a los métodos. Y lo que es más importante, indicarle una fuente de donde obtener los valores de esos parámetros. De este módo el método se ejecutará tantas veces como parámetros tenga su fuente. Para poder hacer esto debemos indicar la anotación 'ParameterizedTest' y la fuente de los mismos, que puede ser:
    • ValueSource
    • EnumSource
    • MethodSource
    • CsvSource
    • CsvFileSource
@ParameterizedTest
@ValueSource(ints = { 1, 2, 3 })
void testWithValueSource(int argument) {
    assertNotNull(argument);
}
La anotación encargada es '@TestFactory'. Los métodos con esta anotación devolverán un Stream,  Collection, Iterable, de la clase DynamicNode o subclases DynamicContainer o DynamicTest. Si devuelve cualquier otra cosa, lanzará una JUnitException. Además este tipo de test no siguen el ciclo de vida normal y no se ven afectados por los @BeforeEach o @AfterEach. 

@TestFactory
Collection<DynamicTest> dynamicTestsFromCollection() {
   return Arrays.asList(
       dynamicTest("1st dynamic test", () -> assertTrue(true)),
       dynamicTest("2nd dynamic test", () -> assertEquals(4, 2 * 2))
   );
}
Con la anotación '@RepeatedTest' se puede indicar a JUnit que repita el método varias veces. Es algo bastante básico en cuanto a la utilidad pero hay varias particularidades interesantes. Para empezar se puede acceder a los objetos 'TestInfo' y 'RepetitionInfo' desde los que se puede acceder al nombre del test, la repetición actual y el total de repeticiones. Además a través del atributo 'name' de la anotación se puede mostrar los valores anteriores en el formato que queramos a través de: {displayName}, {currentRepetition}, {totalRepetitions}.


@RepeatedTest(5)
void repeatedTestWithRepetitionInfo(RepetitionInfo repetitionInfo) {
    assertEquals(5, repetitionInfo.getTotalRepetitions());
}
@RepeatedTest(value = 1, name = "{displayName} {currentRepetition}/{totalRepetitions}")
@DisplayName("Repeat!")
void customDisplayName(TestInfo testInfo) {
    assertEquals(testInfo.getDisplayName(), "Repeat! 1/1");
}
Estos templates no son tests concretos pero si nos permiten indicar el formato de determinados tests. Para ello debemos crear una clase que implemente 'TestTemplateInvocationContextProvider' e indicar dicha clase en el método que queremos que adopte dicho template a través de la anotación '@TestTemplate'.


@TestTemplate
@ExtendWith(MyTestTemplateInvocationContextProvider.class)
void testTemplate(String parameter) {
    assertEquals(3, parameter.length());
}
static class MyTestTemplateInvocationContextProvider implements TestTemplateInvocationContextProvider {
    @Override
    public boolean supportsTestTemplate(ExtensionContext context) {
        return true;
    }
    @Override
    public Stream<TestTemplateInvocationContext> provideTestTemplateInvocationContexts(ExtensionContext context) {
        return Stream.of(invocationContext("foo"), invocationContext("bar"));
    }
}

No hay comentarios:

Publicar un comentario