---
title: "General Fixture"
type: "test-smell"
slug: "general-fixture"
url: "http://localhost:3000/pt-br/test-smells/general-fixture.md"
category: "Maus Cheiros de Fixture"
description: "Uma configuração compartilhada constrói uma única fixture gigante, do tipo “tudo em um”, que cobre as necessidades de todos os testes, mas cada teste individual exercita apenas uma pequena fatia dela."
---
# General Fixture

> Uma configuração compartilhada constrói uma única fixture gigante, do tipo “tudo em um”, que cobre as necessidades de todos os testes, mas cada teste individual exercita apenas uma pequena fatia dela.

## Signs and Symptoms

Um único `beforeEach`/`setUp` (ou uma configuração compartilhada no nível do módulo) constrói muitos objetos, popula muitos registros e prepara vários mocks — e cada teste em particular usa apenas um ou dois deles. A heurística de detecção do catálogo de test smells é simplesmente: _nem todos os campos criados na configuração são usados por todos os métodos de teste_.

Como reconhecê-la:

* O bloco de configuração é longo e cresce toda vez que um novo teste é adicionado.
* Para entender um único teste, você precisa rolar a tela para cima e fazer engenharia reversa de quais partes da fixture realmente importam para ele.
* Muitos testes falham ou precisam ser editados quando você altera um objeto compartilhado com o qual a maioria deles nem se importa.
* A mesma fixture atende, a partir de um único lugar, cenários radicalmente diferentes (criação, validação, pagamento, permissões).

```js
// Smell: uma fixture para tudo; cada teste usa só uma fração dela
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', () => {
  // só precisa de cart + product, mas paga por admin, order, gateway, zone…
  expect(cart.subtotal()).toBe(10);
});

```

## Reasons for the Problem

**Por que acontece**

* **DRY aplicado de forma agressiva demais.** A configuração é consolidada em um único hook compartilhado para “evitar duplicação”, então as necessidades de cada novo teste são acopladas à mesma fixture.
* **Crescimento orgânico.** A fixture vai acumulando objetos à medida que testes são adicionados, e ninguém poda o que os testes antigos não usam mais.
* **Inércia da configuração implícita.** Uma vez que existe um `beforeEach` grande, adicionar mais uma linha é mais fácil do que criar uma fixture focada para o novo caso.

**Por que é prejudicial**

* **Legibilidade / Testes como Documentação.** Um teste deveria se ler como uma relação clara de causa→efeito. Quando a maior parte da fixture é ruído irrelevante, o leitor não consegue dizer o que de fato determina o resultado. O antídoto de Meszaros, a _Minimal Fixture_ (fixture mínima), existe justamente porque um teste que usa a menor fixture possível é sempre mais fácil de entender.
* **Manutenibilidade.** Uma mudança exigida por um teste (por exemplo, dar a `product` um novo campo obrigatório) força edições na configuração compartilhada por todos os testes, gerando quebras em cascata e acoplando testes não relacionados entre si.
* **Confiabilidade.** Um estado de fixture compartilhado e mutável permite que os testes influenciem uns aos outros e torna difícil localizar as falhas — uma fonte clássica de instabilidade dependente da ordem de execução.
* **Velocidade.** Cada teste paga o custo total de construir a fixture inteira. A General Fixture é listada entre as causas de Slow Tests (testes lentos).
* **Falsa confiança.** Os testes ficam superespecificados em relação a detalhes incidentais da fixture, de modo que passam ou falham por razões não relacionadas ao comportamento sob teste.

## Treatment

Busque uma **Minimal Fixture** (fixture mínima): cada teste configura apenas o que aquele teste precisa, e nada mais.

1. **Inventarie o uso.** Para cada campo compartilhado, liste quais testes de fato o leem. Tudo o que é usado apenas por um subconjunto é candidato a sair da configuração compartilhada.
2. **Empurre a construção para Creation Methods / builders de dados de teste (Delegated Setup).** Mantenha os testes concisos sem forçar uma fixture gigante — cada teste chama um builder e sobrescreve apenas os atributos relevantes para ele.
3. **Prefira uma Fresh Fixture por teste** em vez de uma compartilhada de vida longa, eliminando o acoplamento entre testes e o estado compartilhado mutável.
4. **Divida por cenário.** Se grupos de testes realmente compartilham uma fixture _pequena_, separe-os em blocos `describe` focados (ou classes de teste), cada um com sua própria configuração mínima.
5. **Mantenha no `beforeEach` apenas o que é verdadeiramente comum e pequeno;** mova o restante para dentro do teste, de modo que causa e efeito fiquem ao lado da asserção.

```js
// Antes: general fixture em um hook compartilhado (ver Sinais e Sintomas)

// Depois: configuração mínima e delegada — cada teste constrói só o que precisa
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);
});

```

Agora cada teste se lê de cima a baixo como uma história autocontida, os builders absorvem o código repetitivo e mudar um cenário não perturba mais os demais.
