Acceso a bases de datos con JDBC: tutorial completo Java 21

Las pruebas de JDBC deben usar una base de datos real (o embebida H2 en modo MySQL), no mocks. Los mocks de JDBC raramente detectan errores reales del driver o de las constraints de la BD.

Test de integración con JUnit 5 y H2

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

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class ProductoDaoJdbcTest {

    static DataSource ds;
    static ProductoDao dao;

    @BeforeAll
    static void configurar() throws Exception {
        HikariConfig cfg = new HikariConfig();
        cfg.setJdbcUrl("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;MODE=MySQL");
        cfg.setUsername("sa"); cfg.setPassword("");
        ds = new HikariDataSource(cfg);

        // Crear esquema
        try (Connection c = ds.getConnection(); Statement st = c.createStatement()) {
            st.execute("CREATE TABLE productos (id INT AUTO_INCREMENT PRIMARY KEY, nombre VARCHAR(100) NOT NULL, precio DOUBLE NOT NULL, activo BOOLEAN DEFAULT TRUE)");
        }
        dao = new ProductoDaoJdbc(ds);
    }

    @Test @Order(1)
    void guardar_y_recuperar_por_id() {
        Producto p = new Producto("Ratón óptico", 29.99);
        int id = dao.save(p);
        assertTrue(id > 0);

        Optional<Producto> recuperado = dao.findById(id);
        assertTrue(recuperado.isPresent());
        assertEquals("Ratón óptico", recuperado.get().nombre());
        assertEquals(29.99, recuperado.get().precio(), 0.001);
    }

    @Test @Order(2)
    void actualizar_producto() {
        Producto original = new Producto("Viejo nombre", 10.0);
        int id = dao.save(original);

        Producto actualizado = new Producto(id, "Nuevo nombre", 15.0, true);
        boolean ok = dao.update(actualizado);
        assertTrue(ok);

        Producto leido = dao.findById(id).orElseThrow();
        assertEquals("Nuevo nombre", leido.nombre());
    }

    @Test @Order(3)
    void eliminar_producto() {
        Producto p = new Producto("Borrar esto", 5.0);
        int id = dao.save(p);
        assertTrue(dao.delete(id));
        assertFalse(dao.findById(id).map(Producto::activo).orElse(true));
    }

    @AfterAll
    static void limpiar() throws Exception {
        ((HikariDataSource) ds).close();
    }
}

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP
ARTÍCULO ANTERIOR