---
title: "General Fixture"
type: "test-smell"
slug: "general-fixture"
url: "http://localhost:3000/es/test-smells/general-fixture.md"
category: "Olores de fixtures"
description: "Una configuración compartida construye un gran fixture «todo en uno» que cubre las necesidades de todas las pruebas, pero cada prueba individual ejercita solo una pequeña parte de él."
---
# General Fixture

> Una configuración compartida construye un gran fixture «todo en uno» que cubre las necesidades de todas las pruebas, pero cada prueba individual ejercita solo una pequeña parte de él.

## Signs and Symptoms

Un único `beforeEach`/`setUp` (o una configuración compartida a nivel de módulo) construye montones de objetos, siembra muchos registros y conecta varios mocks, y cualquier prueba dada toca solo uno o dos de ellos. La heurística de detección del catálogo de test smells es simplemente: _no todos los campos creados en la configuración son usados por todos los métodos de prueba_.

Cómo reconocerlo:

* El bloque de configuración es largo y crece cada vez que se añade una prueba nueva.
* Para entender una sola prueba debes desplazarte hacia arriba y deducir por ingeniería inversa qué partes del fixture le importan realmente.
* Muchas pruebas fallan o necesitan edición cuando cambias un objeto compartido que a la mayoría de ellas ni siquiera les importa.
* El mismo fixture sirve a escenarios completamente distintos (creación, validación, pago, permisos) desde un único lugar.

```js
// Olor: un fixture para todo; cada prueba usa solo una porción
let user, admin, product, cart, order, paymentGateway, shippingZone;

beforeEach(() => {
  user            = createUser({ name: 'Ada' });
  admin           = createAdmin();
  product         = createProduct({ price: 10 });
  cart            = createCart(user, [product]);
  order           = createOrder(cart);
  paymentGateway  = mockGateway();
  shippingZone    = createZone('EU');
});

test('cart subtotal sums its line items', () => {
  // solo necesita cart + product, pero paga por admin, order, gateway, zone…
  expect(cart.subtotal()).toBe(10);
});

```

## Reasons for the Problem

**Por qué ocurre**

* **DRY aplicado de forma demasiado agresiva.** La configuración se consolida en un único hook compartido para "evitar la duplicación", de modo que las necesidades de cada nueva prueba se atornillan al mismo fixture.
* **Crecimiento orgánico.** El fixture va acumulando objetos a medida que se añaden pruebas, y nadie poda lo que las pruebas más antiguas ya no usan.
* **Inercia de la configuración implícita.** Una vez que existe un `beforeEach` grande, añadir una línea más es más fácil que crear un fixture enfocado para el nuevo caso.

**Por qué duele**

* **Legibilidad / Pruebas-como-Documentación.** Una prueba debería leerse como una clara relación causa→efecto. Cuando la mayor parte del fixture es ruido irrelevante, el lector no puede saber qué impulsa realmente el resultado. El antídoto de Meszaros, el _Minimal Fixture_, existe precisamente porque una prueba que usa el fixture más pequeño siempre es más fácil de entender.
* **Mantenibilidad.** Un cambio exigido por una prueba (p. ej., dar a `product` un nuevo campo obligatorio) obliga a editar una configuración compartida por todas las pruebas, creando roturas en cadena y acoplando entre sí pruebas no relacionadas.
* **Fiabilidad.** El estado mutable y compartido del fixture permite que las pruebas se influyan entre sí y dificulta localizar los fallos: una fuente clásica de fragilidad dependiente del orden.
* **Velocidad.** Cada prueba paga el coste completo de construir todo el fixture. General Fixture figura entre las causas de las Slow Tests.
* **Falsa confianza.** Las pruebas acaban sobreespecificadas frente a detalles incidentales del fixture, de modo que pasan o fallan por razones ajenas al comportamiento bajo prueba.

## Treatment

Apunta a un **Minimal Fixture**: cada prueba configura solo lo que esa prueba necesita, y nada más.

1. **Inventaría el uso.** Para cada campo compartido, enumera qué pruebas lo leen realmente. Cualquier cosa usada solo por un subconjunto es candidata a salir de la configuración compartida.
2. **Lleva la construcción a Creation Methods / builders de datos de prueba (Delegated Setup).** Mantén las pruebas concisas sin forzar un único fixture gigante: cada prueba llama a un builder y sobrescribe solo los atributos relevantes para ella.
3. **Prefiere un Fresh Fixture por prueba** en lugar de uno compartido de larga vida, eliminando el acoplamiento entre pruebas y el estado mutable compartido.
4. **Divide por escenario.** Si grupos de pruebas comparten genuinamente un fixture _pequeño_, sepáralos en bloques `describe` enfocados (o clases de prueba), cada uno con su propia configuración mínima.
5. **Mantén en `beforeEach` solo lo que sea verdaderamente común y pequeño;** mueve el resto en línea para que la causa y el efecto queden junto a la aserción.

```js
// Antes: general fixture en un hook compartido (ver Signos y Síntomas)

// Después: configuración mínima y delegada: cada prueba construye solo lo que necesita
test('cart subtotal sums its line items', () => {
  const cart = aCart().withItem(aProduct().price(10)).build();
  expect(cart.subtotal()).toBe(10);
});

test('checkout charges the payment gateway', () => {
  const gateway = mockGateway();
  const cart    = aCart().withItem(aProduct().price(10)).build();

  checkout(cart, gateway);

  expect(gateway.charge).toHaveBeenCalledWith(10);
});

```

Ahora cada prueba se lee de arriba abajo como una historia autocontenida, los builders absorben el código repetitivo, y cambiar un escenario ya no perturba a los demás.
