commit e533abf7b304f62c6fbd28263bd62f14679e8e87 Author: Isidoro Nevares Date: Wed Apr 22 17:37:53 2026 +0200 commit inicial diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..ae68f90 --- /dev/null +++ b/.env.example @@ -0,0 +1,6 @@ +# Información de configuración de la base de datos +DB_HOST=localhost +DB_PORT=3306 +DB_NAME=mapa_mundi +DB_USER= +DB_PASSWORD= \ No newline at end of file diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml new file mode 100644 index 0000000..15158f4 --- /dev/null +++ b/.github/workflows/ci-cd.yml @@ -0,0 +1,49 @@ +name: Primer flujo de trabajo CI/CD (Build, Test and Push Docker Image) para Ampliación de Entornos de Desarrollo + +# ===== Permisos del token automático de GitHub para que pueda "subir"(push del paso 4.) la imagen docker generada en el paso 3. +# ===== La imagen se subirá al área de registro de GitHub ghcr.io/profies/aaee_mapamundi_sb ===== +permissions: + contents: read + packages: write + +# ===== Disparadores del workflow ===== +on: + push: + branches: + - '**' # Cualquier rama + +# ===== Tareas del workflow ===== +jobs: + build-and-push: + runs-on: ubuntu-latest + + steps: + + # 1. Descarga código + - name: Checkout code + uses: actions/checkout@v3 + + # 2. JDK/Maven para tests previos + - name: Configución pasar TEST + uses: actions/setup-java@v3 + with: + distribution: temurin + java-version: 23 + + - name: Construir proyecto con Maven + run: mvn clean package + + # 3. Construir la imagen Docker usando el Dockerfile + - name: Build Docker image + run: docker build -t ghcr.io/${{ github.repository }}:latest . + + # 4. Push a GHCR (GitHub Container Registry) + - name: Push Docker image + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Push image + run: docker push ghcr.io/${{ github.repository }}:latest \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0293886 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +/bin/ +*.class +/target/ +# Eclipse +.classpath +.project +.settings/ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..32e642a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,29 @@ +# ====== Etapa 1: Fase de construcción (es temporal)====== +# Usamos una imagen de Maven con JDK 23 para construir la aplicación +FROM maven:3.9-eclipse-temurin-23 AS imagen_construccion + +# +WORKDIR /app +COPY pom.xml . + +COPY src ./src +RUN mvn clean package + +# ====== Etapa 2: Fase de ejecución (con la que generará la imagen) ====== +# En teoría sólo necesitamos la JRE para ejecutar la aplicación (ojo, a veces puede dar problemas y se usa la JDK ) +# No se necesita el entorno de construcción completo (Maven + JDK + src), sólo el resultado de la construcción (el .jar) y un entorno de ejecución (JRE) +FROM eclipse-temurin:23-jre AS imagen_ejecucion + +WORKDIR /app + +# Copia el jar generado: lo que se obtendría (aaee_mapamundi-0.0.1.jar según el pom.xml) se copia como app.jar +# LA idea es simplificar el comando de arranque +COPY --from=imagen_construccion /app/target/*.jar app.jar + +# Puerto típico de Spring Boot (se podría cambiar si la aplicación usa otro) +EXPOSE 8080 + +# Comando de arranque +# En las actividades anteriores se ejectuaba el comando "java -jar target/aaee_mapamundi-0.0.1.jar" (info en el pom.xml) para iniciar la aplicación +# Aquí se hace lo mismo pero apuntando al jar copiado en esta etapa +ENTRYPOINT ["java", "-jar", "app.jar"] \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..753aed9 --- /dev/null +++ b/README.md @@ -0,0 +1,47 @@ +# Repositorio para el taller de Ampliación de Entornos - CI/CD con GitHub Actions. + +## 📦 Archivos principales para CI/CD con Docker y GitHub Actions + +### 1. `.github/workflows/ci-cd.yml` +Pipeline de CI/CD usando GitHub Actions. + +- Automatiza procesos al hacer cambios en el repositorio +- Permite integrar testing, build y despliegue continuo +- Construye la imagen Docker +- Publica la imagen en un registro como GHCR (gitHub Container Registry) + +--- + +### 2. `Dockerfile` +Define cómo se construye la imagen Docker de la aplicación. + +- Describe el entorno de ejecución (imagen base) +- Indica qué archivos se incluyen en la imagen +- Define cómo se arranca la aplicación dentro del contenedor + +--- + +### 3. `docker-compose.yml` +Define y orquesta múltiples servicios Docker. + +- Permite levantar varios contenedores (app, base de datos, etc.) +- Centraliza la configuración de red, volúmenes y dependencias +- Facilita el entorno de desarrollo y pruebas local + +--- + +### 4. `.env.example` +Plantilla de variables de entorno necesarias para la aplicación. + +- Documenta qué variables son requeridas +- Sirve como base para crear un `.env` real (no versionado) +- Evita exponer credenciales sensibles en el repositorio + +--- + +## Resumen +- `.github/workflows/ci-cd.yml` → automatización CI/CD +- `Dockerfile` → construcción de la imagen +- `docker-compose.yml` → orquestación de servicios +- `.env.example` → plantilla de configuración (se usará en docker-compose.yml) + diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..f9481ae --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,28 @@ +services: + app: + image: ghcr.io/profies/taller_aaee_hogwarts_sb:latest + container_name: aaee_hogwarts_sb + ports: + - "8080:8080" + env_file: + - .env + depends_on: + - db + restart: always + + db: + image: mysql:8.0 + container_name: bbdd_hogwarts + environment: + MYSQL_DATABASE: ${DB_NAME} + MYSQL_USER: ${DB_USER} + MYSQL_PASSWORD: ${DB_PASSWORD} + MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD} + ports: + - "3306:3306" + volumes: + - db_data:/var/lib/mysql + restart: always + +volumes: + db_data: diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..c36e3ba --- /dev/null +++ b/pom.xml @@ -0,0 +1,66 @@ + + 4.0.0 + org.lapaloma.hogwarts + aaee_hogwarts + 0.0.2 + + Prueba de Springboot + Proyecto para poder probar el funcionamiento de SpringBoot + + + org.springframework.boot + spring-boot-starter-parent + 4.0.1 + + + + UTF-8 + 23 + 6.0.3 + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + com.mysql + mysql-connector-j + runtime + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/org/lapaloma/hogwarts/AppHogwartsSB.java b/src/main/java/org/lapaloma/hogwarts/AppHogwartsSB.java new file mode 100644 index 0000000..b2607bf --- /dev/null +++ b/src/main/java/org/lapaloma/hogwarts/AppHogwartsSB.java @@ -0,0 +1,14 @@ +package org.lapaloma.hogwarts; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class AppHogwartsSB { + + public static void main(String[] args) { + SpringApplication.run(AppHogwartsSB.class, args); + + } + +} \ No newline at end of file diff --git a/src/main/java/org/lapaloma/hogwarts/controller/CasaController.java b/src/main/java/org/lapaloma/hogwarts/controller/CasaController.java new file mode 100644 index 0000000..6dd08f7 --- /dev/null +++ b/src/main/java/org/lapaloma/hogwarts/controller/CasaController.java @@ -0,0 +1,53 @@ +/** + * + */ +package org.lapaloma.hogwarts.controller; + +import java.util.List; + +import org.lapaloma.hogwarts.service.CasaService; +import org.lapaloma.hogwarts.vo.Casa; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * Isidoro Nevares Martín - Virgen de la Paloma Fecha creación: 13 mar 2026 + */ +@RestController +@RequestMapping("/hogwarts/casas") +public class CasaController { + + private final CasaService casaService; + + // Spring inyecta automáticamente el service con su DAO + public CasaController(CasaService casaService) { + this.casaService = casaService; + } + + // GET /hogwarts/casas - listar todos las casas + @GetMapping + public List getAll() { + List listaCasas = casaService.obtenerListaCasas(); + return listaCasas; + } + + // GET /hogwarts/casas/id/{id} - Obtener un Casa por su código + @GetMapping("/id/{id}") + public ResponseEntity getByCodigo(@PathVariable("id") Integer identificador) { + Casa Casa = casaService.obtenerCasaPorClave(identificador); + + return Casa != null ? ResponseEntity.ok(Casa) : ResponseEntity.notFound().build(); + } + + // GET /hogwarts/casas/nombre/{nombre} - Obtener un Casa por su nombre + @GetMapping("/nombre/{nombre}") + public List getByNombre(@PathVariable("nombre") String nombre) { + List listaCasas = casaService.obtenerCasaPorNombre(nombre); + + return listaCasas; + } + +} diff --git a/src/main/java/org/lapaloma/hogwarts/dao/ICasaDAO.java b/src/main/java/org/lapaloma/hogwarts/dao/ICasaDAO.java new file mode 100644 index 0000000..6a4e054 --- /dev/null +++ b/src/main/java/org/lapaloma/hogwarts/dao/ICasaDAO.java @@ -0,0 +1,19 @@ +package org.lapaloma.hogwarts.dao; + +import java.util.List; + +import org.lapaloma.hogwarts.vo.Casa; + +public interface ICasaDAO { + public Casa obtenerCasaPorClave(int identificador); + + public void actualizarCasa(Casa Casa); + + public void crearCasa(Casa Casa); + + public void borrarCasa(Casa Casa); + + public List obtenerListaCasas(); + + public List obtenerCasaPorNombre(String nombre); +} diff --git a/src/main/java/org/lapaloma/hogwarts/dao/impl/CasaDaoJDBC.java b/src/main/java/org/lapaloma/hogwarts/dao/impl/CasaDaoJDBC.java new file mode 100644 index 0000000..9af649c --- /dev/null +++ b/src/main/java/org/lapaloma/hogwarts/dao/impl/CasaDaoJDBC.java @@ -0,0 +1,186 @@ +package org.lapaloma.hogwarts.dao.impl; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +import javax.sql.DataSource; + +import org.lapaloma.hogwarts.dao.ICasaDAO; +import org.lapaloma.hogwarts.vo.Casa; +import org.springframework.stereotype.Repository; + +@Repository +public class CasaDaoJDBC implements ICasaDAO { + private final DataSource dataSource; + + // Spring inyecta el DataSource configurado automáticamente + public CasaDaoJDBC(DataSource dataSource) { + this.dataSource = dataSource; + } + + @Override + public Casa obtenerCasaPorClave(int identificador) { + Casa Casa = null; + + String sentenciaSQL = """ + SELECT * FROM casa + WHERE idCasa =? + """; + + try (Connection conexion = dataSource.getConnection(); + PreparedStatement sentenciaJDBCPreparada = conexion.prepareStatement(sentenciaSQL);) { + + sentenciaJDBCPreparada.setInt(1, identificador); + System.out.println(sentenciaJDBCPreparada); + + ResultSet resultadoSentencia = sentenciaJDBCPreparada.executeQuery(); + + if (resultadoSentencia.next()) { + Casa = getLineaFromResultSet(resultadoSentencia); + } + + } catch (Exception e) { + e.printStackTrace(); + } + + return Casa; + } + + @Override + public void actualizarCasa(Casa Casa) { + + String sentenciaSQL = """ + UPDATE casa + SET Nombre=? + WHERE idCasa=? + """; + + try (Connection conexion = dataSource.getConnection(); + PreparedStatement sentenciaJDBCPreparada = conexion.prepareStatement(sentenciaSQL);) { + + sentenciaJDBCPreparada.setString(1, Casa.getNombre()); + sentenciaJDBCPreparada.setInt(2, Casa.getIdentificador()); + + System.out.println(sentenciaJDBCPreparada); + + sentenciaJDBCPreparada.executeUpdate(); + + } catch (Exception e) { + e.printStackTrace(); + } + + } + + @Override + public void crearCasa(Casa Casa) { + + String sentenciaSQL = """ + INSERT INTO casa (idCasa, Nombre) + VALUES (?, ?) + """; + + try (Connection conexion = dataSource.getConnection(); + PreparedStatement sentenciaJDBCPreparada = conexion.prepareStatement(sentenciaSQL);) { + + sentenciaJDBCPreparada.setInt(1, Casa.getIdentificador()); + sentenciaJDBCPreparada.setString(2, Casa.getNombre()); + + System.out.println(sentenciaJDBCPreparada); + + sentenciaJDBCPreparada.executeUpdate(); + + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public void borrarCasa(Casa Casa) { + + String sentenciaSQL = """ + DELETE FROM casa + WHERE idCasa=? + """; + + try (Connection conexion = dataSource.getConnection(); + PreparedStatement sentenciaJDBCPreparada = conexion.prepareStatement(sentenciaSQL);) { + + sentenciaJDBCPreparada.setInt(1, Casa.getIdentificador()); + sentenciaJDBCPreparada.executeUpdate(); + + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public List obtenerListaCasas() { + + List lista = new ArrayList<>(); + + String sentenciaSQL = """ + SELECT * FROM casa + """; + + try (Connection conexion = dataSource.getConnection(); + PreparedStatement sentenciaJDBCPreparada = conexion.prepareStatement(sentenciaSQL);) { + + System.out.println(sentenciaJDBCPreparada); + + ResultSet resultadoSentencia = sentenciaJDBCPreparada.executeQuery(); + + while (resultadoSentencia.next()) { + lista.add(getLineaFromResultSet(resultadoSentencia)); + } + + } catch (Exception e) { + e.printStackTrace(); + } + + return lista; + } + + @Override + public List obtenerCasaPorNombre(String nombre) { + + List lista = new ArrayList<>(); + + String sentenciaSQL = """ + SELECT * FROM casa + WHERE Nombre LIKE ? + """; + + try (Connection conexion = dataSource.getConnection(); + PreparedStatement sentenciaJDBCPreparada = conexion.prepareStatement(sentenciaSQL);) { + + sentenciaJDBCPreparada.setString(1, "%" + nombre + "%"); + + System.out.println(sentenciaJDBCPreparada); + + ResultSet resultadoSentencia = sentenciaJDBCPreparada.executeQuery(); + + while (resultadoSentencia.next()) { + lista.add(getLineaFromResultSet(resultadoSentencia)); + } + + } catch (Exception e) { + e.printStackTrace(); + } + + return lista; + } + + private Casa getLineaFromResultSet(ResultSet resultadoSentencia) throws SQLException { + + Casa Casa = new Casa(); + + Casa.setIdentificador(resultadoSentencia.getInt("idCasa")); + Casa.setNombre(resultadoSentencia.getString("Nombre")); + + return Casa; + } +} \ No newline at end of file diff --git a/src/main/java/org/lapaloma/hogwarts/excepcion/CasaNoEncontradaException.java b/src/main/java/org/lapaloma/hogwarts/excepcion/CasaNoEncontradaException.java new file mode 100644 index 0000000..d907103 --- /dev/null +++ b/src/main/java/org/lapaloma/hogwarts/excepcion/CasaNoEncontradaException.java @@ -0,0 +1,12 @@ +package org.lapaloma.hogwarts.excepcion; + +public class CasaNoEncontradaException extends RuntimeException { + /** + * + */ + private static final long serialVersionUID = -3344627619585104664L; + + public CasaNoEncontradaException(String mensaje) { + super(mensaje); + } +} diff --git a/src/main/java/org/lapaloma/hogwarts/service/CasaService.java b/src/main/java/org/lapaloma/hogwarts/service/CasaService.java new file mode 100644 index 0000000..75398cb --- /dev/null +++ b/src/main/java/org/lapaloma/hogwarts/service/CasaService.java @@ -0,0 +1,76 @@ +/** + * + */ +package org.lapaloma.hogwarts.service; + +import java.util.List; + +import org.lapaloma.hogwarts.dao.ICasaDAO; +import org.lapaloma.hogwarts.excepcion.CasaNoEncontradaException; +import org.lapaloma.hogwarts.vo.Casa; +import org.springframework.stereotype.Service; + +@Service +public class CasaService { + + private final ICasaDAO casaDAO; + + // Spring inyecta el DAO automáticamente + public CasaService(ICasaDAO casaDAO) { + this.casaDAO = casaDAO; + } + + + public Casa obtenerCasaPorClave(Integer identificador) { + + + if (identificador == null || identificador <= 0) { + throw new IllegalArgumentException("Código inválido"); + } + + Casa Casa = casaDAO.obtenerCasaPorClave(identificador); + + + if (Casa == null) { + throw new CasaNoEncontradaException( + "No existe una casa con idenficador: " + identificador + ); + } + + return Casa; + } + + public List obtenerListaCasas() { + + List lista = casaDAO.obtenerListaCasas(); + + // Esto provoca error + //lista = null; + + if (lista == null || lista.isEmpty()) { + throw new RuntimeException("No hay casas disponibles"); + } + + return lista; + } + + public List obtenerCasaPorNombre(String nombre) { + + if (nombre == null || nombre.isBlank()) { + throw new IllegalArgumentException("Nombre inválido"); + } + + List lista = casaDAO.obtenerCasaPorNombre(nombre); + + // Esto provoca error s + //lista =null; + + if (lista == null || lista.isEmpty()) { + throw new CasaNoEncontradaException( + "No existen casas con nombre: " + nombre + ); + } + + return lista; + } +} \ No newline at end of file diff --git a/src/main/java/org/lapaloma/hogwarts/vo/Casa.java b/src/main/java/org/lapaloma/hogwarts/vo/Casa.java new file mode 100644 index 0000000..b1678a0 --- /dev/null +++ b/src/main/java/org/lapaloma/hogwarts/vo/Casa.java @@ -0,0 +1,50 @@ +package org.lapaloma.hogwarts.vo; + +/** + * + * Casa: Clase de persistencia que representa una Casa de Hogwarts. + * + * @author Isidoro Nevares Martín - IES Virgen de la Paloma + * @date 03 marzo 2026 + * + * + */ +public class Casa { + private int identificador; + private String nombre; + + /** + * @param identificador + * @param nombre + */ + public Casa(int identificador, String nombre) { + super(); + this.identificador = identificador; + this.nombre = nombre; + } + + public Casa() { + } + + public int getIdentificador() { + return identificador; + } + + public void setIdentificador(int identificador) { + this.identificador = identificador; + } + + public String getNombre() { + return nombre; + } + + public void setNombre(String nombre) { + this.nombre = nombre; + } + + @Override + public String toString() { + return "Casa [identificador=" + identificador + ", nombre=" + nombre + "]"; + } + +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 0000000..14f89a4 --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,13 @@ +# Puerto en que escucha Spring Boot +server.port=8080 + +# Servicio de la base de datos. +# Ejemplo url base dator: +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver +spring.datasource.url=jdbc:mysql://${DB_HOST:192.168.1.36}:${DB_PORT:3306}/${DB_NAME:Hogwarts} +spring.datasource.username=${DB_USER:root} +spring.datasource.password=${DB_PASSWORD:mysql_123} + +# Parámetros del Pool de conexiones HikariCP +spring.datasource.hikari.maximum-pool-size=10 +spring.datasource.hikari.minimum-idle=2 \ No newline at end of file diff --git a/src/test/java/org/lapaloma/hogwarts/service/CasaServiceTest.java b/src/test/java/org/lapaloma/hogwarts/service/CasaServiceTest.java new file mode 100644 index 0000000..ee63474 --- /dev/null +++ b/src/test/java/org/lapaloma/hogwarts/service/CasaServiceTest.java @@ -0,0 +1,165 @@ +package org.lapaloma.hogwarts.service; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.lapaloma.hogwarts.dao.ICasaDAO; +import org.lapaloma.hogwarts.excepcion.CasaNoEncontradaException; +import org.lapaloma.hogwarts.vo.Casa; + +class CasaServiceTest { + + private CasaService casaService; + private FakeCasaDAO fakeDAO; + + @BeforeEach + void setUp() { + fakeDAO = new FakeCasaDAO(); + casaService = new CasaService(fakeDAO); + } + + // ========================= + // obtenerCasaPorClave + // ========================= + + @Test + void obtenerCasaPorClave_cuandoCodigoEsNull_lanzaExcepcion() { + assertThrows(IllegalArgumentException.class, () -> { + casaService.obtenerCasaPorClave(null); + }); + } + + @Test + void obtenerCasaPorClave_cuandoCodigoEstaVacio_lanzaExcepcion() { + assertThrows(IllegalArgumentException.class, () -> { + casaService.obtenerCasaPorClave(0); + }); + } + + @Test + void obtenerCasaPorClave_cuandoNoExiste_lanzaExcepcion() { + assertThrows(CasaNoEncontradaException.class, () -> { + casaService.obtenerCasaPorClave(99); + }); + } + + @Test + void obtenerCasaPorClave_cuandoExiste_retornaCasa() { + fakeDAO.crearCasa(new Casa(2, "Slytherin")); + + Casa resultado = casaService.obtenerCasaPorClave(2); + + assertNotNull(resultado); + assertEquals("Slytherin", resultado.getNombre()); + } + + // ========================= + // obtenerListaCasas + // ========================= + + @Test + void obtenerListaCasas_cuandoListaEstaVacia_lanzaExcepcion() { + assertThrows(RuntimeException.class, () -> { + casaService.obtenerListaCasas(); + }); + } + + @Test + void obtenerListaCasas_cuandoHayDatos_retornaLista() { + fakeDAO.crearCasa(new Casa(2, "Slytherin")); + + List resultado = casaService.obtenerListaCasas(); + + assertNotNull(resultado); + assertEquals(1, resultado.size()); + } + + // ========================= + // obtenerCasaPorNombre + // ========================= + + @Test + void obtenerCasaPorNombre_cuandoNombreEsNull_lanzaExcepcion() { + assertThrows(IllegalArgumentException.class, () -> { + casaService.obtenerCasaPorNombre(null); + }); + } + + @Test + void obtenerCasaPorNombre_cuandoNombreEstaVacio_lanzaExcepcion() { + assertThrows(IllegalArgumentException.class, () -> { + casaService.obtenerCasaPorNombre(""); + }); + } + + @Test + void obtenerCasaPorNombre_cuandoNoExiste_lanzaExcepcion() { + assertThrows(CasaNoEncontradaException.class, () -> { + casaService.obtenerCasaPorNombre("Inexistente"); + }); + } + + @Test + void obtenerCasaPorNombre_cuandoExiste_retornaLista() { + fakeDAO.crearCasa(new Casa(2, "Slytherin")); + + List resultado = casaService.obtenerCasaPorNombre("Slytherin"); + + assertEquals(1, resultado.size()); + } + + // ========================= + // Fake DAO. Se crea el DAO dentro del test para no depender de la conexión a la base de datos, de si hay red, de si accede a un fichero... + // En caso de usar el DOA real (CasaDaoJDBC) estaríamos hablando de prubeas de integración. + // ========================= + + static class FakeCasaDAO implements ICasaDAO { + + private List data = new ArrayList<>(); + + @Override + public Casa obtenerCasaPorClave(int identificador) { + return data.stream() + .filter(c -> c.getIdentificador()==identificador) + .findFirst() + .orElse(null); + } + + @Override + public List obtenerListaCasas() { + return new ArrayList<>(data); + } + + @Override + public List obtenerCasaPorNombre(String nombre) { + List resultado = new ArrayList<>(); + + for (Casa c : data) { + if (c.getNombre().equals(nombre)) { + resultado.add(c); + } + } + return resultado; + } + + @Override + public void actualizarCasa(Casa Casa) { + } + + @Override + public void crearCasa(Casa Casa) { + data.add(Casa); + } + + @Override + public void borrarCasa(Casa Casa) { + + } + } +} \ No newline at end of file