Introducción a las pruebas unitarias con JUnit 4

Tarea 1: Prueba de un método básico

Esta tarea cosniste en crear una prueba JUnit 4 para un método simple. Comience creando un proyecto Java y una clase con un método que calcule el valor absoluto de un número entero.

Código de la clase bajo prueba

public class ValorUtil {

    /**
     * Retorna el valor absoluto de un entero.
     * @param numero el número de entrada.
     * @return el valor absoluto del parámetro.
     */
    public static int obtenerAbsoluto(int numero) {
        return Math.abs(numero);
    }
}

Creación de la clase de prueba

A continuación, se crea una clase de prueba para verificar la funcionalidad del método obtenerAbsoluto. Se utiliza la anotación @Before para inicializar una variable de prueba.

import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class ValorUtilTest {

    private int valorNegativo;

    @Before
    public void configuracionInicial() {
        // Se prepara un valor negativo para la prueba
        valorNegativo = -15;
    }

    @Test
    public void pruebaValorAbsoluto() {
        int resultado = ValorUtil.obtenerAbsoluto(valorNegativo);
        // Se verifica que el resultado sea positivo (valor absoluto)
        assertEquals("El valor absoluto de -15 debe ser 15", 15, resultado);
    }
}

Tarea 2: Pruebas para una clase con múltiples métodos

En este ejercicio se prueba una clase que simula una calculadora. La implementación contiene errores intencionales para demostrar cómo los tests los detectan.

Implementación de la calculadora (con errores)

public class Calculadora {
    private int resultadoAcumulado; // Variable para almacenar el estado

    public void sumar(int valor) {
        resultadoAcumulado += valor;
    }

    public void restar(int valor) {
        // ERROR INTENCIONAL: Debería ser resultadoAcumulado - valor
        resultadoAcumulado = resultadoAcumulado - 1;
    }

    public void multiplicar(int valor) {
        // Método aún no implementado
    }

    public void dividir(int valor) {
        resultadoAcumulado /= valor;
    }

    public void elevarAlCuadrado(int valor) {
        resultadoAcumulado = valor * valor;
    }

    public void calcularRaizCuadrada(int valor) {
        // ERROR: Bucle infinito
        while(true) {
            // No hace nada
        }
    }

    public void reiniciar() {
        resultadoAcumulado = dice;
    }

    public int obtenerResultado() {
        return resultadoAcumulado;
    }
}

Pruebas para cada funcionalidad

import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;

public class CalculadoraTest {
    private Calculadora calc;

    @Before
    public void preparar() {
        calc = new Calculadora();
        calc.reiniciar();
    }

    @Test
    public void testSuma() {
        calc.sumar(25);
        assertEquals(25, calc.obtenerResultado());
    }

    @Test
    public void testRestaConError() {
        calc.sumar(100); // Resultado = 100
        calc.restar(1);  // Error: resta 1 en lugar del valor dado
        // Esta aserción fallará, exponiendo el bug
        assertNotEquals(99, calc.obtenerResultado());
    }

    @Test
    public void testMultiplicacionNoImplementada() {
        calc.multiplicar(5);
        // El método no hace nada, el resultado permanece en 0
        assertEquals(0, calc.obtenerResultado());
    }

    @Test
    public void testDivision() {
        calc.sumar(20);
        calc.dividir(4);
        assertEquals(5, calc.obtenerResultado());
    }

    @Test
    public void testCuadrado() {
        calc.elevarAlCuadrado(6);
        assertEquals(36, calc.obtenerResultado());
    }

    @Test(timeout =的活动Seconds) // Timeout para detectar bucle infinito
    public void testRaizCuadradaConBucle() {
        calc.calcularRaizCuadrada(9);
    }
}

Tarea 3: Prueba de un algoritmo para años bisiestos

Se implementa y prueba la lógica para determinar si un año es bisiesto según las reglas del calendario gregoriano.

public class AnalizadorBisiesto {

    public static boolean esBisiesto(int año) {
        if (año % 400 == 0) {
            return true;
        } else if (año % 100 == 0) {
            return false;
        } else if (año % 4 == 0) {
            return true;
        } else {
            return false;
        }
    }
}

Pruebas con diferentes casos

import org.junit.Test;
import static org.junit.Assert.*;

public class AnalizadorBisiestoTest {

    @Test
    public void testAñoDivisiblePor400() {
        assertTrue("2000 debería ser bisiesto", AnalizadorBisiesto.esBisiesto(2000));
    }

    @Test
    public void testAñoDivisiblePor100PeroNoPor400() {
        assertFalse("2100 no debería ser bisiesto", AnalizadorBisiesto.esBisiesto(2100));
    }

    @Test
    public void testAñoDivisiblePor4PeroNoPor100() {
        assertTrue("2024 debería ser bisiesto", AnalizadorBisiesto.esBisiesto(2024));
    }

    @Test
    public void testAñoNoDivisiblePor4() {
        assertFalse("2023 no debería ser bisiesto", AnalizadorBisiesto.esBisiesto(2023));
    }
}

Tarea 4: Clasificación de triángulos

Este ejemplo prueba un método que clasifica triángulos en función de la longitud de sus lados, manjeando la precisión con BigDecimal.

import java.math.BigDecimal;

public class ClasificadorTriangulos {

    public static String clasificar(BigDecimal ladoA, BigDecimal ladoB, BigDecimal ladoC) {
        if (ladoA == null || ladoB == null || ladoC == null) {
            return "Parámetros inválidos";
        }

        // Condición de existencia del triángulo
        if (ladoA.add(ladoB).compareTo(ladoC) > 0 &&
            ladoA.add(ladoC).compareTo(ladoB) > 0 &&
            ladoB.add(ladoC).compareTo(ladoA) > 0) {

            BigDecimal aCuadrado = ladoA.multiply(ladoA);
            BigDecimal bCuadrado = ladoB.multiply(ladoB);
            BigDecimal cCuadrado = ladoC.multiply(ladoC);

            // Verificar triángulo rectángulo (Teorema de Pitágoras)
            boolean esRectangulo = aCuadrado.add(bCuadrado).compareTo(cCuadrado) == 0 ||
                                   aCuadrado.add(cCuadrado).compareTo(bCuadrado) == 0 ||
                                   bCuadrado.add(cCuadrado).compareTo(aCuadrado) == 0;

            // Clasificación por lados
            if (ladoA.compareTo(ladoB) == 0 && ladoB.compareTo(ladoC) == 0) {
                return "Equilátero";
            } else if (ladoA.compareTo(ladoB) == 0 || ladoB.compareTo(ladoC) == 0 || ladoA.compareTo(ladoC) == 0) {
                return esRectangulo ? "Rectángulo Isósceles" : "Isósceles";
            } else if (esRectangulo) {
                return "Rectángulo Escaleno";
            } else {
                return "Escaleno";
            }
        } else {
            return "No forma un triángulo";
        }
    }
}

Pruebas para diferentes tipos de triángulos

import org.junit.Test;
import java.math.BigDecimal;
import static org.junit.Assert.*;

public class ClasificadorTriangulosTest {

    @Test
    public void testTrianguloEquilatero() {
        BigDecimal lado = new BigDecimal("5.0");
        String resultado = ClasificadorTriangulos.clasificar(lado, lado, lado);
        assertEquals("Equilátero", resultado);
    }

    @Test
    public void testTrianguloIsosceles() {
        BigDecimal resultado = ClasificadorTriangulos.clasificar(
            new BigDecimal("7.0"),
            new BigDecimal("7.0"),
            new BigDecimal("10.0")
        );
        assertEquals("Isósceles", resultado);
    }

    @Test
    public void testTrianguloRectangulo() {
        // Lados 3, 4, 5 (triplete pitagórico)
        String resultado = ClasificadorTriangulos.clasificar(
            new BigDecimal("3.0"),
            new BigDecimal("4.0"),
            new BigDecimal("5.0")
        );
        assertEquals("Rectángulo Escaleno", resultado);
    }

    @Test
    public void testNoEsTriangulo() {
        String resultado = ClasificadorTriangulos.clasificar(
            new BigDecimal("1.0"),
            new BigDecimal("2.0"),
            new BigDecimal("10.0")
        );
        assertEquals("No forma un triángulo", resultado);
    }
}

Etiquetas: JUnit java Pruebas Unitarias Desarrollo dirigido por pruebas integración continua

Publicado el 9-5 21:54