Commit inicial

This commit is contained in:
Isidoro Nevares Martín 2026-03-16 10:47:22 +01:00
commit edbd3bdded
15 changed files with 612 additions and 0 deletions

44
.classpath Normal file
View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="optional" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk-23">
<attributes>
<attribute name="module" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="target/generated-sources/annotations">
<attributes>
<attribute name="ignore_optional_problems" value="true"/>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="m2e-apt" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations">
<attributes>
<attribute name="ignore_optional_problems" value="true"/>
<attribute name="test" value="true"/>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="m2e-apt" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/bin/
*.class
/target/

34
.project Normal file
View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>eedd_ra3_ejemplo4</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
<filteredResources>
<filter>
<id>1772465433562</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription>

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
org.eclipse.jdt.apt.aptEnabled=false

View File

@ -0,0 +1,9 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
org.eclipse.jdt.core.compiler.processAnnotations=disabled
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=1.8

View File

@ -0,0 +1,4 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1

127
README.md Normal file
View File

@ -0,0 +1,127 @@
# JUnit 5 Conceptos básicos
---
## 1. Anotaciones esenciales de JUnit 5
JUnit 5 usa anotaciones para indicar qué métodos son tests y cómo preparar o limpiar el entorno.
| Anotación | Cuándo se ejecuta | Para qué sirve |
|---|---|---|
| `@Test` | En cada test | Marca un método como test |
| `@BeforeEach` | Antes de cada test | Preparar el estado común (crear objetos, etc.) |
| `@AfterEach` | Después de cada test | Limpiar recursos (cerrar conexiones, etc.) |
| `@BeforeAll` | Una vez antes de todos | Inicializar recursos costosos (se ejecuta una sola vez) |
| `@AfterAll` | Una vez después de todos | Liberar recursos globales |
> **Nota:** Los métodos `@BeforeAll` y `@AfterAll` deben ser `static`.
### Ejemplo
```java
class AlumnoServiceTest {
private AlumnoService service;
@BeforeEach
void setUp() {
service = new AlumnoService(); // Se ejecuta antes de cada @Test
}
@Test
void telefonoDe9DigitosEsValido() {
// ...
}
@Test
void telefonoVacioNoEsValido() {
// ...
}
}
```
En este ejemplo, `setUp()` crea una instancia nueva de `AlumnoService` antes de **cada** test, garantizando que los tests son independientes entre sí.
---
## 2. Nomenclatura de los tests
El nombre del método de test es muy importante: cuando un test falla, el nombre es lo primero que se lee.
### Convención recomendada
```
metodo_cuandoCondicion_retornaResultado()
```
| Parte | Significado |
|---|---|
| `metodo` | El método que se está probando |
| `cuandoCondicion` | La situación o entrada que se usa |
| `retornaResultado` | Lo que se espera que ocurra |
### Ejemplos
```java
// ✅ Nombres descriptivos
@Test
void telefonoValido_cuandoTiene9Digitos_retornaTrue() { ... }
@Test
void telefonoValido_cuandoEstaVacio_retornaFalse() { ... }
@Test
void telefonoValido_cuandoTieneLetras_retornaFalse() { ... }
// ❌ Nombres que no dicen nada
@Test
void test1() { ... }
@Test
void pruebaTest() { ... }
```
Con nombres descriptivos, si falla `telefonoValido_cuandoTiene9Digitos_retornaTrue` sabemos exactamente qué está fallando sin ni siquiera abrir el código.
---
## 3. Given When Then (G-W-T)
El patrón **Given-When-Then** es una forma de estructurar los tests que viene del enfoque **BDD (Behavior Driven Development)**. Es equivalente al patrón AAA pero con una terminología más orientada al comportamiento.
| Fase | Significado | Equivalente AAA |
|---|---|---|
| **Given** | Dado un contexto inicial | Arrange |
| **When** | Cuando ocurre una acción | Act |
| **Then** | Entonces se produce un resultado | Assert |
### Ejemplo
```java
@Test
void telefonoValido_cuandoTiene9Digitos_retornaTrue() {
// Given
Alumno alumno = new Alumno();
alumno.setTelefono("123456789");
// When
boolean resultado = service.telefonoValido(alumno);
// Then
assertTrue(resultado);
}
```
La ventaja de G-W-T es que el test **se lee casi como una frase en lenguaje natural**:
> *Dado un alumno con teléfono de 9 dígitos, cuando compruebo si es válido, entonces el resultado es verdadero.*
Esto facilita que cualquier componente del equipo, incluso sin conocimientos técnicos, entienda qué se está probando.
![Diagrama de pruebas](img/junit_test_flowchart.svg)
---
Fuentes: [ChatGPT](https://chat.openai.com) + [Claude](https://claude.ai)

View File

@ -0,0 +1,98 @@
<svg width="100%" viewBox="0 0 680 780" xmlns="http://www.w3.org/2000/svg">
<defs>
<marker id="arrow" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M2 1L8 5L2 9" fill="none" stroke="context-stroke" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</marker>
<mask id="imagine-text-gaps-ws0lrq" maskUnits="userSpaceOnUse"><rect x="0" y="0" width="680" height="780" fill="white"/><rect x="220.1922607421875" y="16.155502319335938" width="239.76734924316406" height="21.102027893066406" fill="black" rx="2"/><rect x="297.9148864746094" y="59.4489860534668" width="83.35580444335938" height="21.102027893066406" fill="black" rx="2"/><rect x="245.95347595214844" y="76.26336669921875" width="189.2511444091797" height="19.473262786865234" fill="black" rx="2"/><rect x="116" y="127.78427124023438" width="93.79690551757812" height="19.473262786865234" fill="black" rx="2"/><rect x="290.30548095703125" y="159.44898986816406" width="98.57457733154297" height="21.102027893066406" fill="black" rx="2"/><rect x="269.5641784667969" y="176.26336669921875" width="141.10049438476562" height="19.473262786865234" fill="black" rx="2"/><rect x="315.32232666015625" y="237.44898986816406" width="49.06757736206055" height="21.102027893066406" fill="black" rx="2"/><rect x="226.00001525878906" y="263.448974609375" width="47.179420471191406" height="21.102027893066406" fill="black" rx="2"/><rect x="307.2546691894531" y="264.26336669921875" width="146.65394592285156" height="19.473262786865234" fill="black" rx="2"/><rect x="225.1856231689453" y="309.448974609375" width="48.28647232055664" height="21.102027893066406" fill="black" rx="2"/><rect x="302.91552734375" y="310.26336669921875" width="155.03570556640625" height="19.473262786865234" fill="black" rx="2"/><rect x="225.1856231689453" y="355.4490051269531" width="42.05135726928711" height="21.102027893066406" fill="black" rx="2"/><rect x="288.6956481933594" y="356.26336669921875" width="182.13027954101562" height="19.473262786865234" fill="black" rx="2"/><rect x="294.9054870605469" y="439.448974609375" width="89.37460327148438" height="21.102027893066406" fill="black" rx="2"/><rect x="259.98248291015625" y="456.2633361816406" width="160.70367431640625" height="19.473262786865234" fill="black" rx="2"/><rect x="614.6202392578125" y="310.26336669921875" width="47.63090133666992" height="19.473262786865234" fill="black" rx="2"/><rect x="302.514892578125" y="551.448974609375" width="74.15583038330078" height="21.102027893066406" fill="black" rx="2"/><rect x="266.5484313964844" y="568.2633666992188" width="148.06346130371094" height="19.473262786865234" fill="black" rx="2"/><rect x="265.26324462890625" y="623.7842407226562" width="150.63656616210938" height="19.473262786865234" fill="black" rx="2"/><rect x="143.2101593017578" y="659.448974609375" width="145.57969665527344" height="21.102027893066406" fill="black" rx="2"/><rect x="385.1659240722656" y="659.448974609375" width="157.3724822998047" height="21.102027893066406" fill="black" rx="2"/><rect x="149.68704223632812" y="691.7842407226562" width="132.78673553466797" height="19.473262786865234" fill="black" rx="2"/><rect x="392.5716857910156" y="691.7842407226562" width="142.714599609375" height="19.473262786865234" fill="black" rx="2"/><rect x="238.6240234375" y="725.7842407226562" width="203.5201873779297" height="19.473262786865234" fill="black" rx="2"/></mask></defs>
<!-- Título -->
<text x="340" y="32" text-anchor="middle" font-size="15" style="fill:rgb(20, 20, 19);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:14px;font-weight:500;text-anchor:middle;dominant-baseline:auto">Ciclo de vida de un test con JUnit 5</text>
<!-- @BeforeAll -->
<g style="fill:rgb(0, 0, 0);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto">
<rect x="215" y="52" width="250" height="44" rx="8" stroke-width="0.5" style="fill:rgb(241, 239, 232);stroke:rgb(95, 94, 90);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<text x="340" y="70" text-anchor="middle" dominant-baseline="central" style="fill:rgb(68, 68, 65);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:14px;font-weight:500;text-anchor:middle;dominant-baseline:central">@BeforeAll</text>
<text x="340" y="86" text-anchor="middle" dominant-baseline="central" style="fill:rgb(95, 94, 90);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:12px;font-weight:400;text-anchor:middle;dominant-baseline:central">Una vez antes de todos los tests</text>
</g>
<line x1="340" y1="96" x2="340" y2="124" marker-end="url(#arrow)" style="fill:none;stroke:rgb(115, 114, 108);color:rgb(0, 0, 0);stroke-width:1.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<!-- Loop starts -->
<!-- Indicador de repetición -->
<rect x="100" y="124" width="480" height="380" rx="12" fill="none" stroke="var(--color-border-tertiary)" stroke-width="1" stroke-dasharray="6 4" style="fill:none;stroke:rgba(31, 30, 29, 0.15);color:rgb(0, 0, 0);stroke-width:1px;stroke-dasharray:6px, 4px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<text x="120" y="142" fill="var(--color-text-tertiary)" style="fill:rgb(61, 61, 58);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:12px;font-weight:400;text-anchor:start;dominant-baseline:auto">por cada @Test</text>
<!-- @BeforeEach -->
<g style="fill:rgb(0, 0, 0);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto">
<rect x="215" y="152" width="250" height="44" rx="8" stroke-width="0.5" style="fill:rgb(225, 245, 238);stroke:rgb(15, 110, 86);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<text x="340" y="170" text-anchor="middle" dominant-baseline="central" style="fill:rgb(8, 80, 65);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:14px;font-weight:500;text-anchor:middle;dominant-baseline:central">@BeforeEach</text>
<text x="340" y="186" text-anchor="middle" dominant-baseline="central" style="fill:rgb(15, 110, 86);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:12px;font-weight:400;text-anchor:middle;dominant-baseline:central">Prepara el estado inicial</text>
</g>
<line x1="340" y1="196" x2="340" y2="224" marker-end="url(#arrow)" style="fill:none;stroke:rgb(115, 114, 108);color:rgb(0, 0, 0);stroke-width:1.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<!-- @Test con las 3 fases -->
<g style="fill:rgb(0, 0, 0);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto">
<rect x="190" y="224" width="300" height="180" rx="10" stroke-width="0.5" style="fill:rgb(238, 237, 254);stroke:rgb(83, 74, 183);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<text x="340" y="248" text-anchor="middle" dominant-baseline="central" style="fill:rgb(60, 52, 137);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:14px;font-weight:500;text-anchor:middle;dominant-baseline:central">@Test</text>
<!-- Given -->
<rect x="206" y="258" width="268" height="40" rx="6" fill="none" stroke="var(--color-border-secondary)" stroke-width="0.5" style="fill:rgb(238, 237, 254);stroke:rgb(83, 74, 183);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<text x="230" y="274" dominant-baseline="central" font-size="12" style="fill:rgb(60, 52, 137);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:14px;font-weight:500;text-anchor:start;dominant-baseline:central">Given</text>
<text x="380" y="274" text-anchor="middle" dominant-baseline="central" style="fill:rgb(83, 74, 183);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:12px;font-weight:400;text-anchor:middle;dominant-baseline:central">Preparar objetos y datos</text>
<!-- When -->
<rect x="206" y="304" width="268" height="40" rx="6" fill="none" stroke="var(--color-border-secondary)" stroke-width="0.5" style="fill:rgb(238, 237, 254);stroke:rgb(83, 74, 183);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<text x="230" y="320" dominant-baseline="central" font-size="12" style="fill:rgb(60, 52, 137);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:14px;font-weight:500;text-anchor:start;dominant-baseline:central">When</text>
<text x="380" y="320" text-anchor="middle" dominant-baseline="central" style="fill:rgb(83, 74, 183);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:12px;font-weight:400;text-anchor:middle;dominant-baseline:central">Llamar al método a probar</text>
<!-- Then -->
<rect x="206" y="350" width="268" height="40" rx="6" fill="none" stroke="var(--color-border-secondary)" stroke-width="0.5" style="fill:rgb(238, 237, 254);stroke:rgb(83, 74, 183);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<text x="230" y="366" dominant-baseline="central" font-size="12" style="fill:rgb(60, 52, 137);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:14px;font-weight:500;text-anchor:start;dominant-baseline:central">Then</text>
<text x="380" y="366" text-anchor="middle" dominant-baseline="central" style="fill:rgb(83, 74, 183);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:12px;font-weight:400;text-anchor:middle;dominant-baseline:central">Verificar el resultado esperado</text>
</g>
<line x1="340" y1="404" x2="340" y2="432" marker-end="url(#arrow)" style="fill:none;stroke:rgb(115, 114, 108);color:rgb(0, 0, 0);stroke-width:1.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<!-- @AfterEach -->
<g style="fill:rgb(0, 0, 0);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto">
<rect x="215" y="432" width="250" height="44" rx="8" stroke-width="0.5" style="fill:rgb(225, 245, 238);stroke:rgb(15, 110, 86);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<text x="340" y="450" text-anchor="middle" dominant-baseline="central" style="fill:rgb(8, 80, 65);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:14px;font-weight:500;text-anchor:middle;dominant-baseline:central">@AfterEach</text>
<text x="340" y="466" text-anchor="middle" dominant-baseline="central" style="fill:rgb(15, 110, 86);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:12px;font-weight:400;text-anchor:middle;dominant-baseline:central">Limpia recursos tras el test</text>
</g>
<!-- Flecha de vuelta al bucle -->
<path d="M580 454 L620 454 L620 176 L580 176" fill="none" stroke="var(--color-border-secondary)" stroke-width="1" stroke-dasharray="4 3" marker-end="url(#arrow)" mask="url(#imagine-text-gaps-ws0lrq)" style="fill:none;stroke:rgba(31, 30, 29, 0.3);color:rgb(0, 0, 0);stroke-width:1px;stroke-dasharray:4px, 3px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<text x="638" y="320" text-anchor="middle" dominant-baseline="central" transform="rotate(90,638,320)" style="fill:rgb(61, 61, 58);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:12px;font-weight:400;text-anchor:middle;dominant-baseline:central">repetir</text>
<line x1="340" y1="516" x2="340" y2="544" marker-end="url(#arrow)" style="fill:none;stroke:rgb(115, 114, 108);color:rgb(0, 0, 0);stroke-width:1.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<!-- @AfterAll -->
<g style="fill:rgb(0, 0, 0);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto">
<rect x="215" y="544" width="250" height="44" rx="8" stroke-width="0.5" style="fill:rgb(241, 239, 232);stroke:rgb(95, 94, 90);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<text x="340" y="562" text-anchor="middle" dominant-baseline="central" style="fill:rgb(68, 68, 65);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:14px;font-weight:500;text-anchor:middle;dominant-baseline:central">@AfterAll</text>
<text x="340" y="578" text-anchor="middle" dominant-baseline="central" style="fill:rgb(95, 94, 90);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:12px;font-weight:400;text-anchor:middle;dominant-baseline:central">Una vez al finalizar todos</text>
</g>
<!-- Leyenda GWT = AAA -->
<rect x="100" y="618" width="480" height="136" rx="10" fill="none" stroke="var(--color-border-tertiary)" stroke-width="0.5" style="fill:none;stroke:rgba(31, 30, 29, 0.15);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<text x="340" y="638" text-anchor="middle" style="fill:rgb(61, 61, 58);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:12px;font-weight:400;text-anchor:middle;dominant-baseline:auto">Equivalencia de patrones</text>
<!-- Columnas -->
<line x1="340" y1="648" x2="340" y2="740" stroke="var(--color-border-tertiary)" stroke-width="0.5" mask="url(#imagine-text-gaps-ws0lrq)" style="fill:rgb(0, 0, 0);stroke:rgba(31, 30, 29, 0.15);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<g style="fill:rgb(0, 0, 0);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto">
<rect x="116" y="652" width="200" height="36" rx="6" stroke-width="0.5" style="fill:rgb(238, 237, 254);stroke:rgb(83, 74, 183);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<text x="216" y="670" text-anchor="middle" dominant-baseline="central" style="fill:rgb(60, 52, 137);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:14px;font-weight:500;text-anchor:middle;dominant-baseline:central">Given When Then</text>
</g>
<g style="fill:rgb(0, 0, 0);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto">
<rect x="364" y="652" width="200" height="36" rx="6" stroke-width="0.5" style="fill:rgb(250, 236, 231);stroke:rgb(153, 60, 29);color:rgb(0, 0, 0);stroke-width:0.5px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:16px;font-weight:400;text-anchor:start;dominant-baseline:auto"/>
<text x="464" y="670" text-anchor="middle" dominant-baseline="central" style="fill:rgb(113, 43, 19);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:14px;font-weight:500;text-anchor:middle;dominant-baseline:central">Arrange Act Assert</text>
</g>
<text x="216" y="706" text-anchor="middle" style="fill:rgb(61, 61, 58);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:12px;font-weight:400;text-anchor:middle;dominant-baseline:auto">Given → When → Then</text>
<text x="464" y="706" text-anchor="middle" style="fill:rgb(61, 61, 58);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:12px;font-weight:400;text-anchor:middle;dominant-baseline:auto">Arrange → Act → Assert</text>
<text x="340" y="740" text-anchor="middle" style="fill:rgb(61, 61, 58);stroke:none;color:rgb(0, 0, 0);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;opacity:1;font-family:&quot;Anthropic Sans&quot;, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, sans-serif;font-size:12px;font-weight:400;text-anchor:middle;dominant-baseline:auto">= misma idea, distinta terminología</text>
</svg>

After

Width:  |  Height:  |  Size: 23 KiB

7
pom.xml Normal file
View File

@ -0,0 +1,7 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.lapaloma.concesionario</groupId>
<artifactId>aadd_concesionario</artifactId>
<version>0.0.1-SNAPSHOT</version>
</project>

View File

@ -0,0 +1,22 @@
package org.lapaloma.hogwarts;
/**
*
* AppConcesionario: Clase que realiza el tratamiento de los coches de un
* concesionario.
*
* @author Isidoro Nevares Martín - IES Virgen de la Paloma
* @date 4 dic 2025
*
*
*/
public class AppHogwarts {
public static void main(String[] args) {
AppHogwarts app = new AppHogwarts();
}
}

View File

@ -0,0 +1,71 @@
/**
*
*/
package org.lapaloma.hogwarts.service;
import java.time.LocalDate;
import java.time.Period;
import org.lapaloma.hogwarts.vo.Alumno;
/**
* Isidoro Nevares Martín - Virgen de la Paloma Fecha creación: 9 mar 2026
*/
public class AlumnoService {
public boolean esMayorDeEdad(Alumno alumno) {
boolean esMayor = false;
LocalDate hoy = LocalDate.now();
int edad = Period.between(alumno.getFechaNacimiento(), hoy).getYears();
if (edad > 18) {
esMayor = true;
}
return esMayor;
}
public boolean telefonoValido(Alumno alumno) {
boolean esValido = false;
String telefono = alumno.getTelefono();
if (telefono != null && telefono.length() >= 9) {
esValido = true;
}
return esValido;
}
public String nombreCompleto(Alumno alumno) {
String nombreCompleto = alumno.getApellido1() + " " + alumno.getNombre() + " " + alumno.getApellido2();
return nombreCompleto;
}
public boolean esRepetidor(Alumno alumno) {
boolean esRepetidor = false;
if (alumno.getEsRepetidor() == "") {
esRepetidor = true;
}
return esRepetidor;
}
public boolean alumnoTieneCasa(Alumno alumno) {
boolean tieneCasa = false;
if (alumno.getCasa() != null) {
tieneCasa = true;
}
return tieneCasa;
}
public String obtenerNombreCasa(Alumno alumno) {
String nombreCasa = "Sin casa";
if (!alumno.getCasa().getNombre().isEmpty()) {
nombreCasa = alumno.getCasa().getNombre();
}
return nombreCasa;
}
}

View File

@ -0,0 +1,36 @@
/**
*
*/
package org.lapaloma.hogwarts.service;
import org.lapaloma.hogwarts.vo.Casa;
/**
* Isidoro Nevares Martín - Virgen de la Paloma Fecha creación: 9 mar 2026
*/
public class CasaService {
public boolean tieneNombre(Casa casa) {
boolean tieneNombre = false;
if (casa != null) {
String nombre = casa.getNombre();
tieneNombre = nombre != null && !nombre.trim().isEmpty();
}
return tieneNombre;
}
public String obtenerNnombreEnMayusculas(Casa casa) {
String nombreEnMayusculas = null;
if (tieneNombre(casa)) {
nombreEnMayusculas = casa.getNombre().toUpperCase();
}
return nombreEnMayusculas;
}
public boolean esCasaValida(Casa casa) {
boolean esValida = false;
if (casa != null && casa.getIdentificador() > 0 && tieneNombre(casa)) {
esValida = true;
}
return esValida;
}
}

View File

@ -0,0 +1,110 @@
package org.lapaloma.hogwarts.vo;
import java.time.LocalDate;
/**
*
* Alumno: Clase de persistencia que representa un Alumno de una casa.
*
* @author Isidoro Nevares Martín - IES Virgen de la Paloma
* @date 03 marzo 2026
*
*
*/
public class Alumno {
private int identificador;
String nombre;
private String apellido1;
private String apellido2;
private LocalDate fechaNacimiento;
private String esRepetidor;
private String telefono;
private Casa casa;
public Alumno(int identificador, String nombre, String apellido1, String apellido2, LocalDate fechaNacimiento,
String esRepetidor, String telefono, Casa casa) {
super();
this.identificador = identificador;
this.nombre = nombre;
this.apellido1 = apellido1;
this.apellido2 = apellido2;
this.fechaNacimiento = fechaNacimiento;
this.esRepetidor = esRepetidor;
this.telefono = telefono;
this.casa = 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;
}
public String getApellido1() {
return apellido1;
}
public void setApellido1(String apellido1) {
this.apellido1 = apellido1;
}
public String getApellido2() {
return apellido2;
}
public void setApellido2(String apellido2) {
this.apellido2 = apellido2;
}
public LocalDate getFechaNacimiento() {
return fechaNacimiento;
}
public void setFechaNacimiento(LocalDate fechaNacimiento) {
this.fechaNacimiento = fechaNacimiento;
}
public String getEsRepetidor() {
return esRepetidor;
}
public void setEsRepetidor(String esRepetidor) {
this.esRepetidor = esRepetidor;
}
public String getTelefono() {
return telefono;
}
public void setTelefono(String telefono) {
this.telefono = telefono;
}
public Casa getCasa() {
return casa;
}
public void setCasa(Casa casa) {
this.casa = casa;
}
@Override
public String toString() {
return "Alumno [identificador=" + identificador + ", nombre=" + nombre + ", apellido1=" + apellido1
+ ", apellido2=" + apellido2 + ", fechaNacimiento=" + fechaNacimiento + ", esRepetidor=" + esRepetidor
+ ", telefono=" + telefono + ", casa=" + casa + "]";
}
}

View File

@ -0,0 +1,43 @@
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;
String nombre;
public Casa(int identificador, String nombre) {
super();
this.identificador = identificador;
this.nombre = nombre;
}
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 + "]";
}
}