---
title: "Convidado Misterioso"
type: "test-smell"
slug: "mystery-guest"
url: "http://localhost:3000/pt-br/test-smells/mystery-guest.md"
category: "Maus Cheiros de Fixture"
description: "Um teste cujas entradas ou resultados esperados ficam em um recurso externo — um arquivo, um seed de banco de dados ou uma fixture compartilhada — de modo que você não consegue entender nem confiar no teste apenas lendo-o."
---
# Convidado Misterioso

> Um teste cujas entradas ou resultados esperados ficam em um recurso externo — um arquivo, um seed de banco de dados ou uma fixture compartilhada — de modo que você não consegue entender nem confiar no teste apenas lendo-o.

## Signs and Symptoms

Você não consegue entender um teste apenas lendo-o: os dados que o conduzem (e que justificam suas asserções) ficam em algum lugar fora da tela — um arquivo CSV/JSON, um script de seed de banco de dados, um módulo de fixture compartilhada ou uma anotação de data-fixture do framework. O teste faz referência a um recurso opaco e então faz asserções sobre valores "mágicos" cujo significado está oculto nesse recurso.

Sinais reveladores:

* O corpo chama algo como `readFileSync('fixtures/subscribers.csv')`, `loadSeed('invoices.sql')`, `getResource(...)` ou um `beforeAll` global que popula um banco de dados compartilhado.
* Os valores esperados parecem arbitrários (`toHaveLength(3)`, um id/email específico) e você precisa abrir outro arquivo para descobrir _por quê_.
* Uma fixture compartilhada/"geral" é reutilizada em muitos testes, de modo que as entradas relevantes para _este_ teste ficam soterradas em meio a dados que não lhe interessam.
* Os testes quebram quando um colega edita uma fixture compartilhada para um teste não relacionado.

```js
test('returns active subscribers', async () => {
  // Convidado Misterioso: que linhas há neste arquivo? por que 3 está correto?
  const subscribers = await loadSubscribersFromCsv('./fixtures/subscribers.csv');
  const result = filterActive(subscribers);
  expect(result).toHaveLength(3); // a justificativa fica fora do teste
});

```

O exemplo original do catálogo de Meszaros/Test Smells tem o mesmo formato: `loadAirportsAndFlightsFromFile("test-flights.csv")` seguido de `assertEquals(1, flightsAtOrigin.size())` — o "1" só faz sentido se você ler `test-flights.csv`.

## Reasons for the Problem

**Por que acontece**

* _DRY levado longe demais._ Os dados de teste são extraídos para um arquivo compartilhado ou "fixture geral" a fim de evitar duplicação, trocando legibilidade por reúso.
* _Conveniência com dados do mundo real._ Despejar um CSV/JSON de produção ou um `seed.sql` parece mais fácil do que construir objetos inline.
* _Configuração legada/de integração._ Suítes que sobem um banco de dados compartilhado ou dependem de anotações de data-fixture do framework (`@magentoDataFixture …`) herdam estado oculto por padrão.

**Por que prejudica**

* _Legibilidade / causa e efeito._ O elo entre a entrada e a saída esperada é rompido. Um leitor não consegue ver _por que_ a asserção está correta sem sair do teste, o que anula o papel do teste como documentação executável.
* _Falsa confiança._ Você na verdade não sabe o que o teste exercita; o arquivo pode conter mais (ou menos) do que você supõe, então uma execução verde prova menos do que parece.
* _Confiabilidade / determinismo._ O recurso externo pode estar ausente, ter sido renomeado, reformatado ou diferir conforme o ambiente, o sistema operacional, a codificação ou o locale — as falhas então refletem o estado da _fixture_, e não um defeito real (testes instáveis).
* _Manutenibilidade / acoplamento._ Quando vários testes compartilham um mesmo recurso, qualquer pessoa que o edite para um teste pode quebrar silenciosamente os outros, e ninguém sabe de quais campos cada teste depende.

## Treatment

Torne a entrada _relevante_ visível dentro do teste, ao lado da asserção que depende dela (uma **Fresh Fixture** / configuração inline). O objetivo é que o valor esperado se torne autoevidente.

Passos concretos:

1. **Coloque inline os dados que importam.** Construa, no corpo do teste, os poucos objetos/linhas que interessam ao teste, de modo que o valor esperado da asserção seja obviamente correto.
2. **Se você realmente precisar de um arquivo, construa-o no teste.** Use um helper que receba apenas os parâmetros relevantes e grave em um caminho temporário, e depois faça a limpeza — assim os valores significativos aparecem no teste, não em um blob versionado.
3. **Substitua fixtures compartilhadas/"gerais" por fixtures específicas de cada teste**, ou exponha criadores/buscadores que revelem a intenção (`createProductWithName('Simple Product')`, `getRecentlyAddedProduct()`), para que os atributos em teste fiquem explícitos enquanto a configuração irrelevante permanece escondida atrás de um builder bem nomeado — e não atrás de um recurso opaco.

Antes → depois:

```js
// Antes — Convidado Misterioso: os dados e o "2" estão ocultos em um arquivo de seed
test('flags overdue invoices', async () => {
  await seedDatabaseFromFixture('invoices.sql');
  const overdue = await findOverdueInvoices();
  expect(overdue).toHaveLength(2);
});

// Depois — as entradas estão visíveis; o resultado esperado é óbvio
test('flags overdue invoices', async () => {
  await insertInvoice({ id: 1, dueDate: '2020-01-01', paid: false }); // vencida
  await insertInvoice({ id: 2, dueDate: '2099-01-01', paid: false }); // ainda não vencida
  const overdue = await findOverdueInvoices();
  expect(overdue.map(i => i.id)).toEqual([1]);
});

```

Para o caso do arquivo, prefira um helper focado a um arquivo versionado:

```js
const csv = makeSubscriberCsv(tmpFile, 'active@x.com', 'active@y.com', 'active@z.com');
// agora os "3 ativos" se justificam pelo que você vê no teste, não por um arquivo oculto

```
