---
title: "Igualdade Sensível"
type: "test-smell"
slug: "sensitive-equality"
url: "http://localhost:3000/pt-br/test-smells/sensitive-equality.md"
category: "Maus Cheiros de Asserção"
description: "Um teste verifica o comportamento comparando a representação em string de um objeto (toString(), JSON.stringify(), HTML renderizado) com um literal de string esperado, acoplando o teste a detalhes incidentais de formatação em vez dos valores que realmente importam."
---
# Igualdade Sensível

> Um teste verifica o comportamento comparando a representação em string de um objeto (toString(), JSON.stringify(), HTML renderizado) com um literal de string esperado, acoplando o teste a detalhes incidentais de formatação em vez dos valores que realmente importam.

## Signs and Symptoms

Você reconhece a Igualdade Sensível quando o lado _real_ de uma asserção serializa um objeto em texto e seu lado _esperado_ é um literal de string que agrupa muitos campos com separadores, aspas, colchetes e espaços em branco.

Sinais reveladores:

* O valor real vem de `.toString()`, `String(x)`, um template literal, `JSON.stringify(...)`, `wrapper.html()`, `el.outerHTML` ou de um snapshot de um blob serializado.
* O valor esperado é uma string literal longa (muitas vezes colada de uma execução anterior que falhou) e você não consegue dizer de relance _qual_ parte dela é o que está sendo testado.
* O teste quebra em mudanças que não afetam o comportamento: chaves reordenadas, espaços em branco adicionados/removidos, precisão numérica, formato de data, locale, fuso horário ou ordem de iteração de `Map`/`Set`/objeto.

```js
// Comparando uma forma serializada com um literal de string
expect(JSON.stringify(user)).toBe('{"name":"Bob","age":30}');

// Verificando a saída de toString()
expect(order.toString()).toBe('Order[id=7, total=42.00, items=2]');

// Comparando o HTML renderizado completo com um literal
expect(wrapper.html()).toBe('<div class="card"><h2>Bob</h2><span>30</span></div>');

// Comparação de string sensível a locale/fuso horário
expect(d.toString()).toBe('Mon Jun 15 2026 00:00:00 GMT+0000 (UTC)');

```

## Reasons for the Problem

**Por que acontece**

* É rápido e fácil. Como observam van Deursen et al. em _Refactoring Test Code_, é rápido calcular um resultado real, convertê-lo em string e compará-lo com um literal de string que representa o valor esperado — muitas vezes o literal é apenas copiado de uma execução que falhou. As ferramentas de snapshot tornam isso ainda mais tentador.
* O objeto não tem uma igualdade significativa (`equals`/deep matcher) configurada, ou o grafo de objetos é grande, então despejá-lo em uma string _parece_ mais simples do que verificar campo a campo.

**Por que prejudica**

* **Fragilidade / falsas falhas.** A string carrega muitos detalhes irrelevantes — vírgulas, aspas, espaços, ordenação de chaves, precisão de ponto flutuante, locale, fuso horário, ordem de iteração de coleções. Sempre que o formato de `toString()`/serialização muda, testes não relacionados começam a falhar mesmo que o comportamento esteja correto. Essa é uma causa clássica de [Teste Frágil](http://xunitpatterns.com/Fragile%20Test.html).
* **Manutenibilidade.** Uma única mudança de formatação ou de biblioteca força edições em muitos testes, e o literal esperado gigante é tedioso de atualizar e fácil de errar sutilmente.
* **Legibilidade / intenção obscurecida.** Um valor esperado em forma de muro de texto esconde o que está realmente sendo verificado; um revisor não consegue ver o único campo que importa para o teste.
* **Falsa confiança.** Um blob convertido em string pode passar pelos motivos errados (dois estados distintos que serializam para o mesmo texto), e induz os desenvolvedores a regravar o literal/snapshot quando há falha, sem verificar se o novo valor está de fato correto.
* **Instabilidade (flakiness).** Strings sensíveis a locale, fuso horário e ordenação fazem com que os resultados dependam do ambiente em que o teste é executado.

## Treatment

Verifique os **dados**, não a sua renderização.

1. **Compare valores estruturados com igualdade profunda (deep equality)** em vez de igualdade de string (`toEqual`/`toStrictEqual`), que é independente de ordem e de espaços em branco para objetos.
2. **Verifique apenas os atributos relevantes** com matchers parciais (`toMatchObject`, `expect.objectContaining`), para que uma mudança de formatação em outro lugar não possa quebrar o teste.
3. **Faça o parse, não a comparação por string.** Quando você recebe um payload serializado (por exemplo, um corpo JSON de API), faça o parse de volta para uma estrutura e compare estruturas.
4. **Introduza um método de igualdade/comparação** no objeto (a refatoração que van Deursen et al. recomendam) e verifique a igualdade de objetos em vez da igualdade de `toString()`.
5. **Se você precisar comparar a saída serializada, canonize-a primeiro** — ordene as chaves, fixe locale/fuso horário, defina a precisão numérica — e prefira um snapshot revisado a um literal inline colado à mão.
6. **Para testes de DOM/componentes, consulte de forma semântica** (Testing Library `getByRole`, `toHaveTextContent`) em vez de comparar o HTML completo.

```js
// Antes — Igualdade Sensível
expect(JSON.stringify(user)).toBe('{"name":"Bob","age":30}');

// Depois — igualdade estrutural (independente de ordem de chaves / espaços em branco)
expect(user).toEqual({ name: 'Bob', age: 30 });

// Depois — verifica apenas o campo em teste
expect(user).toMatchObject({ age: 30 });

```

```js
// Antes — comparação por string de um payload de API
expect(res.text).toBe('{"id":7,"total":42}');

// Depois — compara estruturas já parseadas
expect(JSON.parse(res.text)).toEqual({ id: 7, total: 42 });

```
