Como você testa a inexistência de um elemento usando jest e react-testing-library?

102

Tenho uma biblioteca de componentes para a qual estou escrevendo testes de unidade para usar Jest e react-testing-library. Com base em certos adereços ou eventos, quero verificar se certos elementos não estão sendo renderizados.

getByText, getByTestIdetc., lance e erro react-testing-libraryse o elemento não for encontrado, fazendo com que o teste falhe antes do expectdisparo da função.

Como você testa se algo não existe em brincadeira usando a biblioteca react-testing?

SomethingOn
fonte

Respostas:

215

Dos documentos da biblioteca de testes DOM - Aparência e desaparecimento

Elementos de afirmação não estão presentes

Os getBymétodos padrão geram um erro quando não conseguem encontrar um elemento, então se você quiser fazer uma afirmação de que um elemento não está presente no DOM, você pode usar queryByAPIs:

const submitButton = screen.queryByText('submit')
expect(submitButton).toBeNull() // it doesn't exist

A queryAllversão das APIs retorna uma matriz de nós correspondentes. O comprimento da matriz pode ser útil para asserções depois que os elementos são adicionados ou removidos do DOM.

const submitButtons = screen.queryAllByText('submit')
expect(submitButtons).toHaveLength(2) // expect 2 elements

not.toBeInTheDocument

A jest-dombiblioteca de utilitários fornece o .toBeInTheDocument()matcher, que pode ser usado para afirmar se um elemento está no corpo do documento ou não. Isso pode ser mais significativo do que afirmar o resultado de uma consulta null.

import '@testing-library/jest-dom/extend-expect'
// use `queryBy` to avoid throwing an error with `getBy`
const submitButton = screen.queryByText('submit')
expect(submitButton).not.toBeInTheDocument()
kentcdodds
fonte
4
Meus kentcdodds ruins, obrigado. Usei getByTestIde recebi o mesmo erro. E, eu não verifiquei o FAQ, desculpe. Ótima biblioteca! Você pode modificar sua resposta para incluir `.toBeNull ();
Algo em
3
Eu acredito que o link acima foi feito para apontar para o docs reagir testando-biblioteca
PBRE
2
O novo site de documentos foi publicado há poucos dias. Eu deveria ter usado um link mais permanente. Obrigado pela atualização @pbre!
kentcdodds
6
e queryByTextpara aqueles que querem o equivalente a getByTextisso é seguro nulo
S ..
24

Use queryBy/ queryAllBy.

Como você diz, getBy*e getAllBy*lança um erro se nada for encontrado.

No entanto, os métodos equivalentes queryBy*e em queryAllBy*vez disso retornam nullou []:

queryBy

queryBy*as consultas retornam o primeiro nó correspondente para uma consulta e retornam nullse nenhum elemento corresponder. Isso é útil para declarar um elemento que não está presente. Isso ocorre se mais de uma correspondência for encontrada (use queryAllBy em vez disso).

As queryAllBy* consultas queryAllBy retornam uma matriz de todos os nós correspondentes para uma consulta e retornam uma matriz vazia ( []) se nenhum elemento corresponder.

https://testing-library.com/docs/dom-testing-library/api-queries#queryby

Portanto, para os dois específicos que você mencionou, você usaria queryByTexte queryByTestId, mas eles funcionam para todas as consultas, não apenas para esses dois.

Sam
fonte
2
Isso é muito melhor do que a resposta aceita. Esta API é mais recente?
RubbelDieKatz
1
Obrigado pelas palavras amáveis! Essa é basicamente a mesma funcionalidade da resposta aceita , então não acho que seja uma API mais recente (mas posso estar errado). A única diferença real entre esta resposta e a aceita é que a resposta aceita diz que só há um método que faz isso ( queryByTestId) quando na verdade há dois conjuntos inteiros de métodos, dos quais queryByTestIdé um exemplo específico.
Sam
Obrigado, eu prefiro isso do que definir ids de teste
Hylle
14

Você deve usar queryByTestId em vez de getByTestId.

Aqui está um exemplo de código onde eu quero testar se o componente com a id de "carro" não existe.

 describe('And there is no car', () => {
  it('Should not display car mark', () => {
    const props = {
      ...defaultProps,
      base: null,
    }
    const { queryByTestId } = render(
      <IntlProvider locale="fr" messages={fr}>
        <CarContainer{...props} />
      </IntlProvider>,
    );
    expect(queryByTestId(/car/)).toBeNull();
  });
});
Valentin Garreau
fonte
6

getBy * gera um erro ao não encontrar um elemento, então você pode verificar se

expect(() => getByText('your text')).toThrow('Unable to find an element');
Gabriel Vasile
fonte
Isso pode ser muito sujeito a erros. Lançamentos de erros são usados ​​para fins de depuração e não para verificação.
Milen Gardev
2

Você pode usar react-native-testing-library "getAllByType" e, em seguida, verificar se o componente é nulo. Tem a vantagem de não precisar definir TestID, também deve funcionar com componentes de terceiros

 it('should contain Customer component', () => {
    const component = render(<Details/>);
    const customerComponent = component.getAllByType(Customer);
    expect(customerComponent).not.toBeNull();
  });
Andy Rich
fonte
Esse tipo de violação da premissa de não ter detalhes de implementação (como o nome do componente) no teste.
RubbelDieKatz