Estado: NORMATIVO
Referencias de código: Embargos (nebula-treasury), Consecutivos (nebula-masters)
Este documento define cómo se valida una feature backend del ERP Nebula: la
cadena que va desde los casos de prueba de la HTU hasta el gate audit-htu,
pasando por los tests JUnit/Mockito y el umbral JaCoCo. Todas las cifras y
nombres se citan de artefactos reales.
Cada eslabón es bloqueante: un TC de la HTU debe tener un test que lo verifique;
los tests deben superar el umbral JaCoCo; y audit-htu debe dar PASS antes de
declarar la HT entregada o de hacer commit.
La HTU del feature publica los casos en 07_TestCases (formato Gherkin,
derivados de los CA-ALC de la HU V2) y la matriz de cobertura de procesos
R-AUD-COV-02 en 08_Contracts.
architecture/nebula-erp/htu/HT_TES_002_Embargos/07_TestCases/resources/body.md —TC-01..TC-20..../HT_TES_002_Embargos/08_Contracts/resources/body.md — matrizEjemplo de TC (verbatim de 07_TestCases):
TC-06 — Dado todos los obligatorios válidos, cuando Registra,
entonces guarda, "El embargo se registró exitosamente", refresca tabla ·
HTTP 200 · MSG-SUCCESS-001 · CA-ALC2-01 · RN-ALC2-01..06.
embargo)Clases de test del feature embargos
(nebula-treasury/src/test/java/.../v1/embargo/):
| Clase | Capa que cubre |
|---|---|
component/EmbargoComponentTest.java |
Lógica del componente (CRUD + dominio) |
controller/EmbargoControllerTest.java |
Endpoints REST |
validator/EmbargoValidatorTest.java |
Reglas de negocio condicionales |
mapper/EmbargoMapperTest.java |
Mapeo entity ↔ DTO/record + flags |
lightloader/EmbargoLightloaderTest.java |
Enriquecimiento de listas/DTO |
service/EmbargoServiceTest.java |
Servicio |
EmbargoTestData.java |
Fixtures compartidos (no es test) |
Test ilustrativo — EmbargoValidatorTest.java (JUnit 5 + Mockito + AssertJ):
@ExtendWith(MockitoExtension.class)
@DisplayName("EmbargoValidator - validaciones de negocio")
class EmbargoValidatorTest {
@Mock private TreasuryMessages messages;
@InjectMocks private EmbargoValidator validator;
@Test
@DisplayName("levantamiento: fecha futura -> lanza")
void levantamientoFechaFutura() {
EmbargoEntity e = EmbargoTestData.entity("ACTIVO");
LevantamientoDto l = EmbargoTestData.levantamientoDto();
l.setFechaLevantamiento(LocalDate.now().plusDays(1));
assertThatThrownBy(() -> validator.validarLevantamiento(e, l)).isInstanceOf(SimappeException.class);
}
}
Patrón canónico de test: @ExtendWith(MockitoExtension.class), @Mock para
colaboradores, @InjectMocks para el SUT, @DisplayName legible por TC, AssertJ
(assertThatThrownBy / assertThatCode / assertThat) y fixtures centralizados
en EmbargoTestData.
| TC (HTU) | Verifica | Test (método) |
|---|---|---|
| TC-06 | Registro válido: valida, emite consecutivo, persiste | EmbargoComponentTest#createHappy |
| TC-07 | Deudor inexistente/inactivo → 409 | EmbargoComponentTest#createDeudorInactivo |
| TC-08 | Pensión: mayoría de edad ≤ hoy → error | EmbargoValidatorTest#pensionMayoriaPasada |
| TC-09 | Orden judicial duplicada por deudor → 409 | EmbargoComponentTest#createOrdenDuplicada |
| TC-10 | Valor fijo > valor embargo → error | EmbargoValidatorTest#valorFijoMayor |
| TC-11 | Porcentaje fuera de (0,100] → error | EmbargoValidatorTest#porcentajeFueraRango |
| TC-12 | Cuenta inexistente / no de movimiento → 409 | EmbargoComponentTest#createCuentaInvalida |
| TC-15 | Fecha levantamiento ≤ inicio o futura → error | EmbargoValidatorTest#levantamientoFechaInvalida / #levantamientoFechaFutura |
| TC-16 | Levantamiento válido → estado LEVANTADO | EmbargoComponentTest#levantar |
| TC-17 | Embargo LEVANTADO inmutable → 409 al editar | EmbargoComponentTest#updateLevantado |
| TC-18 | Eliminación física de INACTIVO | EmbargoComponentTest#deleteInactivo |
| TC-19 | No eliminable si no es INACTIVO → 409 | EmbargoComponentTest#deleteActivo |
Umbral mínimo 80% de cobertura. Cifras reales (cobertura de instrucción
sobre los paquetes del feature, target/site/jacoco/jacoco.csv):
| Feature | Cobertura instrucción | Cobertura línea |
|---|---|---|
Embargos (v1.embargo.*) |
91.7 % | 91.3 % |
Consecutivos (v1.consecutivo.*) |
92.7 % | 93.2 % |
Cobertura por clase del paquete embargos (instrucción):
| Clase | % |
|---|---|
EmbargoValidator |
100.0 % |
EmbargoMapper |
100.0 % |
EmbargoService |
100.0 % |
EmbargoView |
100.0 % |
EmbargoController |
91.7 % |
EmbargoComponent |
89.5 % |
EmbargoLightloader |
86.1 % |
Nota: el total del módulo completo (incluyendo infra/config/monitoring) queda
por debajo del umbral porque el umbral se evalúa sobre los paquetes del
feature, no sobre clases de plataforma no productivas.
Cómo se corre:
mvn test
mvn jacoco:report # genera target/site/jacoco/index.html + jacoco.csv
audit-htu: gate de estructuraAntes de declarar la HT entregada o de cualquier commit, se ejecuta
audit-htu <ruta-HT> y se lee AUDIT_REPORT.json. Si verdict != "PASS", está
prohibido declarar la HT entregada o hacer commit.
Verifica 7 aserciones (legacy7) + lossless (ASR-08-LOSSLESS):
| ASR | Comprueba |
|---|---|
| ASR-00-001 | Matriz Cobertura de Campos en README (o 00_Coverage.md) |
| ASR-00-002 | Matriz Cobertura de Procesos en 08_Contracts |
| ASR-00-003 | Cero filas ❌ en matriz de campos |
| ASR-00-004 | Cero filas ❌ en matriz de procesos |
| ASR-00-005 | Cada fila ⚠️ con texto en Justificación |
| ASR-01-011 | Toda fila ✅ R-AUD-COV-01 con destino DTO/Entity tiene campo en 01_Model |
| ASR-05-011 | Toda fila ✅ R-AUD-COV-02 con endpoint definido tiene endpoint en 08_Contracts |
| ASR-08-LOSSLESS | Cada artefacto deriva del resources/body.md canónico (sin pérdida) |
AUDIT_REPORT.json de HT_TES_002_Embargos (resumen real):
auditHtuVersion: 8.0verdict: PASSlegacy7: PASS=7, FAIL=0lossless.pass: true (artefactos 01_Model..10_TraceMatrix conlossless: true)✅ HT_TES_002_Embargos → PASS (PASS=7, FAIL=0)
✓ ASR-00-001 ... ✓ ASR-05-011
El gate
audit-htuvalida estructura y trazabilidad, no la corrección
funcional del contenido: por eso la cadena exige además tests + JaCoCo.
05_PRUEBAS_Y_CALIDAD.md — Patrón canónico de feature backend — Nebula ERP