---
title: "Aserción Duplicada"
type: "test-smell"
slug: "duplicate-assert"
url: "http://localhost:3000/es/test-smells/duplicate-assert.md"
category: "Olores de aserción"
description: "Un único método de prueba verifica la misma condición más de una vez —repitiendo una aserción idéntica o volviendo a comprobar lógica equivalente— en lugar de eliminar la comprobación redundante o dividir los casos distintos en sus propias pruebas enfocadas."
---
# Aserción Duplicada

> Un único método de prueba verifica la misma condición más de una vez —repitiendo una aserción idéntica o volviendo a comprobar lógica equivalente— en lugar de eliminar la comprobación redundante o dividir los casos distintos en sus propias pruebas enfocadas.

## Signs and Symptoms

Ves que la **misma aserción aparece dos veces** (mismo matcher, mismos argumentos) en una prueba, o varios bloques de aserción copiados y pegados que difieren solo en valores literales y vuelven a probar el _mismo_ comportamiento. Señales reveladoras:

* Una línea de aserción literalmente idéntica aparece dos o más veces en el cuerpo.
* Muchas llamadas `expect(...)`/`assertEquals(...)` que ejercitan la misma condición con entradas diferentes, todas amontonadas en un método cuyo nombre describe solo un único escenario.
* Aserciones sobrantes de la depuración ("déjame comprobar también X") que nunca se limpiaron.
* El nombre de la prueba (p. ej. `testXmlSanitizer`) no da ninguna pista sobre cuál de sus muchas comprobaciones falló.

```js
test('sanitizer accepts valid input', () => {
  expect(isValid('plain text')).toBe(true);
  expect(isValid('with spaces')).toBe(true);
  expect(isValid('Fritz-box')).toBe(true);   // "el menos es válido"
  expect(isValid('Fritz-box')).toBe(true);   // <-- duplicado exacto, no aporta nada
  expect(isValid('<script>')).toBe(false);
});

```

La línea duplicada `Fritz-box` es la Aserción Duplicada canónica; el olor más amplio es que un método agrupa silenciosamente muchas comprobaciones de la misma condición bajo un solo nombre.

## Reasons for the Problem

**Por qué ocurre**

* **Copiar y pegar.** Se duplica un bloque de aserción y se cambian los literales (o incluso nada).
* **Residuo de depuración.** Quedan olvidadas aserciones adicionales que se añadieron para sondear el comportamiento.
* **Agrupación.** Los desarrolladores prueban "un método" amontonando todos los casos en una sola prueba en lugar de dividirlos, produciendo comprobaciones repetidas y casi idénticas.

**Por qué resulta perjudicial**

* **Falsa confianza.** Una aserción duplicada verdaderamente idéntica añade _cero_ cobertura — nunca puede fallar cuando su gemela pasa — y, aun así, hace que la prueba parezca más exhaustiva de lo que es.
* **Diagnóstico de fallos difícil.** Cuando varias aserciones con la misma forma comparten un método, el informe de fallo apunta al método, no a la entrada concreta que se rompió. Peor aún, una prueba con configuración por defecto se detiene en la primera aserción que falla, así que las comprobaciones duplicadas posteriores nunca se ejecutan — arreglas una, vuelves a ejecutar, te topas con la siguiente (se solapa con la _Ruleta de Aserciones_).
* **Mala legibilidad.** El lector no puede saber si la repetición es intencional (casos distintos) o un error (duplicado real), y el nombre de la prueba documenta solo una de muchas condiciones.
* **Coste de mantenimiento.** Cambia el comportamiento bajo prueba y tendrás que rastrear y actualizar cada aserción duplicada; si te saltas una, la suite se vuelve inconsistente.

## Treatment

1. **Elimina los duplicados exactos.** Si una aserción es idéntica byte a byte a otra de la misma prueba, elimínala — es peso muerto, no cobertura.
2. **Parametriza los casos equivalentes.** Cuando los "duplicados" son en realidad la _misma_ condición con entradas _diferentes_, conviértelos en una prueba de tabla/parametrizada (`test.each` en Jest/Vitest, `@ParameterizedTest` en JUnit 5). Cada fila se reporta y se nombra por separado, de modo que los fallos señalan con precisión la entrada culpable.
3. **Divide las condiciones genuinamente diferentes** en pruebas separadas, cada una con un nombre que indique lo que verifica (`accepts hyphenated host names`, `rejects script tags`).
4. **Nombra según la intención.** El nombre de una prueba debería describir un único comportamiento; si no puedes, esa es una señal para dividir.

```js
// Antes — aserciones duplicadas / agrupadas en una prueba opaca
test('isValid', () => {
  expect(isValid('plain text')).toBe(true);
  expect(isValid('with spaces')).toBe(true);
  expect(isValid('Fritz-box')).toBe(true);
  expect(isValid('Fritz-box')).toBe(true); // duplicado
  expect(isValid('<script>')).toBe(false);
});

// Después — una aserción, cada caso nombrado y reportado de forma independiente
test.each([
  ['plain text', true],
  ['with spaces', true],
  ['Fritz-box',  true],   // el menos es válido
  ['<script>',   false],  // rechaza el marcado
])('isValid(%j) === %s', (input, expected) => {
  expect(isValid(input)).toBe(expected);
});

```

La fila duplicada ha desaparecido, las entradas distintas son explícitas y un fallo nombra el caso exacto.
