En este tema, aprenderemos cómo utilizar la anotación @ParameterizedTest en JUnit para ejecutar un mismo test con diferentes conjuntos de datos. Los tests parametrizados son útiles cuando queremos probar un método con múltiples entradas y verificar que produce las salidas esperadas para cada una de ellas.

¿Qué es @ParameterizedTest?

La anotación @ParameterizedTest en JUnit permite ejecutar un test varias veces con diferentes argumentos. Esto es especialmente útil para evitar la duplicación de código y para asegurarse de que un método funcione correctamente con una variedad de datos de entrada.

Configuración Básica

Para utilizar @ParameterizedTest, necesitamos agregar la dependencia de JUnit 5 en nuestro proyecto. Aquí está el archivo pom.xml para un proyecto Maven:

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.7.0</version>
    <scope>test</scope>
</dependency>

Ejemplo Básico de @ParameterizedTest

Vamos a crear un test parametrizado que verifique si un número es par. Primero, definimos el método que queremos probar:

public class NumberUtils {
    public static boolean isEven(int number) {
        return number % 2 == 0;
    }
}

Ahora, creamos un test parametrizado para este método:

import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.assertFalse;

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

public class NumberUtilsTest {

    @ParameterizedTest
    @ValueSource(ints = {2, 4, 6, 8, 10})
    void testIsEven(int number) {
        assertTrue(NumberUtils.isEven(number));
    }

    @ParameterizedTest
    @ValueSource(ints = {1, 3, 5, 7, 9})
    void testIsNotEven(int number) {
        assertFalse(NumberUtils.isEven(number));
    }
}

Explicación del Código

  • @ParameterizedTest: Indica que el método es un test parametrizado.
  • @ValueSource: Proporciona una lista de valores que se pasarán como argumentos al método de test. En este caso, estamos pasando una lista de enteros.

Proveedores de Argumentos

JUnit 5 proporciona varios proveedores de argumentos que podemos usar con @ParameterizedTest:

  • @ValueSource: Proporciona una lista de valores literales.
  • @EnumSource: Proporciona valores de un tipo enumerado.
  • @CsvSource: Proporciona una lista de valores en formato CSV.
  • @MethodSource: Proporciona valores desde un método estático.

Ejemplo con @CsvSource

Vamos a extender nuestro ejemplo para probar un método que suma dos números:

public class MathUtils {
    public static int add(int a, int b) {
        return a + b;
    }
}

El test parametrizado usando @CsvSource se vería así:

import static org.junit.jupiter.api.Assertions.assertEquals;

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;

public class MathUtilsTest {

    @ParameterizedTest
    @CsvSource({
        "1, 1, 2",
        "2, 3, 5",
        "3, 5, 8",
        "4, 6, 10"
    })
    void testAdd(int a, int b, int expected) {
        assertEquals(expected, MathUtils.add(a, b));
    }
}

Explicación del Código

  • @CsvSource: Proporciona una lista de valores en formato CSV. Cada línea representa un conjunto de argumentos que se pasarán al método de test.

Ejercicio Práctico

Ejercicio

Crea un test parametrizado para un método que verifica si una cadena es un palíndromo. Un palíndromo es una palabra que se lee igual de adelante hacia atrás.

  1. Define el método isPalindrome en una clase StringUtils.
  2. Crea un test parametrizado usando @ValueSource para verificar diferentes cadenas.

Solución

public class StringUtils {
    public static boolean isPalindrome(String str) {
        String cleaned = str.replaceAll("\\s+", "").toLowerCase();
        return new StringBuilder(cleaned).reverse().toString().equals(cleaned);
    }
}
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.assertFalse;

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

public class StringUtilsTest {

    @ParameterizedTest
    @ValueSource(strings = {"madam", "racecar", "radar", "level", "rotor"})
    void testIsPalindrome(String str) {
        assertTrue(StringUtils.isPalindrome(str));
    }

    @ParameterizedTest
    @ValueSource(strings = {"hello", "world", "java", "programming"})
    void testIsNotPalindrome(String str) {
        assertFalse(StringUtils.isPalindrome(str));
    }
}

Conclusión

En esta sección, hemos aprendido cómo usar @ParameterizedTest en JUnit para ejecutar tests con diferentes conjuntos de datos. Hemos visto ejemplos prácticos utilizando @ValueSource y @CsvSource, y hemos creado un ejercicio para reforzar los conceptos aprendidos. En el siguiente tema, exploraremos cómo crear tests parametrizados personalizados para casos más complejos.

© Copyright 2024. Todos los derechos reservados