---
title: "Aserción Redundante"
type: "test-smell"
slug: "redundant-assertion"
url: "http://localhost:3000/es/test-smells/redundant-assertion.md"
category: "Olores de aserción"
description: "Una aserción redundante compara un valor consigo mismo o con un literal que es igual por construcción, por lo que su resultado es fijo y nunca puede fallar realmente ni detectar una regresión."
---
# Aserción Redundante

> Una aserción redundante compara un valor consigo mismo o con un literal que es igual por construcción, por lo que su resultado es fijo y nunca puede fallar realmente ni detectar una regresión.

## Signs and Symptoms

Una aserción es **redundante** cuando su resultado se decide antes incluso de que se ejecute el código bajo prueba: los operandos esperado y real son el _mismo valor_, o ambos son literales que se sabe que son iguales (o desiguales). El catálogo xUnit/Test Smells (Peruma et al.) la define como "un método de prueba que contiene una sentencia de aserción en la que los parámetros esperado y real son el mismo", y señala que la aserción es, por tanto, "o bien siempre verdadera o bien siempre falsa".

Cómo detectarlo:

* Un `assertEquals`/`toBe`/`toEqual` cuyos dos argumentos son la **misma expresión** o variable.
* Un literal booleano afirmado contra sí mismo, p. ej. `assertTrue(true)` o `expect(true).toBe(true)`.
* Una comparación que el compilador/linter puede demostrar que es constante, como `expect(x === x).toBe(true)`.
* Una "comprobación de cordura" que reafirma una constante que acabas de declarar en lugar de ejercitar el sistema.

```js
// Olor: el resultado es fijo, el código bajo prueba nunca interviene
test('user is active', () => {
  expect(true).toBe(true);            // siempre pasa
  const status = 'active';
  expect(status).toBe('active');      // reafirma el literal, no prueba nada
  expect(user.id).toEqual(user.id);   // valor comparado consigo mismo
});

```

Una señal fiable: puedes eliminar por completo el código de producción y la aserción sigue pasando en verde.

## Reasons for the Problem

**Por qué ocurre**

* **Restos de depuración.** El catálogo señala explícitamente que este olor "lo introducen los desarrolladores con fines de depuración y luego lo olvidan": un marcador de posición `assertTrue(true)` codificado de forma fija que sobrevive hasta el commit.
* **Deriva por copiar‑pegar / refactorización.** Se sustituye una variable en ambos lados de un `assertEquals`, o se renombra un valor bajo prueba de modo que el esperado y el real colapsan en el mismo símbolo.
* **Tautología por construcción.** Afirmar un valor contra el literal del que acaba de ser asignado, en lugar de contra una expectativa derivada de forma independiente.
* **Teatro de cobertura.** Se añade una aserción solo para satisfacer reglas del tipo "toda prueba debe afirmar algo", sin comprobar nada significativo.

**Por qué es perjudicial**

* **Falsa confianza.** La prueba está permanentemente en verde y cuenta para el tamaño de la suite y la cobertura, pero no verifica nada. No puede detectar una regresión, así que enmascara huecos en la red de seguridad.
* **La fiabilidad carece de sentido.** Una prueba que nunca puede fallar no aporta ninguna señal; una que siempre es falsa es peso muerto que se ignora o se `skip`ea.
* **Legibilidad.** Los lectores malgastan esfuerzo reconstruyendo el comportamiento previsto a partir de una aserción que afirma una tautología; la prueba ya no documenta un requisito.
* **Mantenibilidad.** Las aserciones redundantes acumulan ruido, inflan las métricas y erosionan la confianza en la suite, animando a la gente a dejar de leer las aserciones con atención.

## Treatment

Reemplaza la tautología por una comprobación que vincule un **valor esperado conocido de forma independiente** con el **resultado real producido por el sistema bajo prueba**.

Pasos:

1. **Identifica la aserción de resultado fijo**: el mismo operando en ambos lados, o dos literales iguales.
2. **Determina la verdadera intención.** ¿Qué comportamiento se suponía que verificaba esta prueba? Si ninguno, la aserción (o toda la prueba) está muerta y debería eliminarse.
3. **Afirma sobre la salida del SUT, no sobre la entrada.** Alimenta el sistema con una entrada real y compara su resultado calculado con un valor esperado codificado de forma fija y calculado a mano, no con una de sus propias entradas/variables.
4. **Mantén esperado/real diferenciados.** Asegúrate de que el operando esperado sea una constante que escribiste a propósito y de que el operando real sea el valor de retorno del código bajo prueba (también corrige el olor relacionado de orden de argumentos incorrecto).
5. **Vuelve a ejecutar con la implementación rota** (mútala) para confirmar que la aserción realmente puede fallar.

```js
// Antes — redundante: el resultado es fijo
test('discount', () => {
  const total = 100;
  expect(total).toBe(100);          // reafirma el literal
  expect(applyDiscount).toBe(applyDiscount); // valor frente a sí mismo
});

// Después — significativo: entrada conocida -> salida esperada de forma independiente
test('applies a 10% discount', () => {
  expect(applyDiscount(100, 0.1)).toBe(90); // resultado del SUT frente a expectativa calculada a mano
});

```

Si quedó un marcador de posición como `assertTrue(true)` de la depuración, elimínalo; si sustituía a una comprobación real, escribe esa comprobación.

## Detected by

- **sonar** `javascript:S5863` — A las aserciones no se les debe pasar dos veces el mismo argumento (https://rules.sonarsource.com/javascript/RSPEC-5863/)
- **sonar** `java:S5863` — A las aserciones no se les debe pasar dos veces el mismo argumento (https://rules.sonarsource.com/java/RSPEC-5863/)
- **eslint** `no-constant-binary-expression` — Prohibir expresiones donde la operación no afecta al valor (marca autocomparaciones / aserciones siempre verdaderas como assert(a === a)) (https://eslint.org/docs/latest/rules/no-constant-binary-expression)
