¿Cómo se prueba la inexistencia de un elemento usando jest y react-testing-library?

95

Tengo una biblioteca de componentes para la que estoy escribiendo pruebas unitarias para usar Jest y react-testing-library. Basado en ciertos accesorios o eventos, quiero verificar que ciertos elementos no se estén renderizando.

getByText, getByTestId, Etc tiro y el error en react-testing-librarysi no se encuentra el elemento que causa el error de la prueba antes de que los expectfuegos de función.

¿Cómo se prueba para algo que no existe en broma usando react-testing-library?

SomethingOn
fuente

Respuestas:

200

De DOM Testing-library Docs - Apariencia y desaparición

Los elementos de afirmación no están presentes

Los getBymétodos estándar arrojan un error cuando no pueden encontrar un elemento, por lo que si desea hacer una afirmación de que un elemento no está presente en el DOM, puede usar queryByAPI en su lugar:

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

La queryAllversión de las API devuelve una matriz de nodos coincidentes. La longitud de la matriz puede ser útil para las afirmaciones después de que se agregan o eliminan elementos del DOM.

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

not.toBeInTheDocument

La jest-dombiblioteca de utilidades proporciona el .toBeInTheDocument()comparador, que se puede usar para afirmar que un elemento está en el cuerpo del documento o no. Esto puede ser más significativo que afirmar el resultado de una 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
fuente
4
Mis malos kentcdodds, gracias. Usé getByTestIdy obtuve el mismo error. Y no miré las preguntas frecuentes, lo siento. ¡Gran biblioteca! ¿Puede modificar su respuesta para incluir el `.toBeNull ();
SomethingOn
3
Creo que el enlace anterior estaba destinado a apuntar a los documentos de la biblioteca de pruebas de
reacción
2
El nuevo sitio de documentos se publicó hace unos días. Debería haber usado un enlace más permanente. ¡Gracias por la actualización @pbre!
kentcdodds
6
y queryByTextpara aquellos que quieran el equivalente a getByTexteso es nulo seguro
S ..
22

Utilice queryBy/ queryAllBy.

Como dices, getBy*y getAllBy*arroja un error si no se encuentra nada.

Sin embargo, los métodos equivalentes queryBy*y queryAllBy*en su lugar devuelven nullo []:

queryBy

queryBy*las consultas devuelven el primer nodo coincidente para una consulta y devuelven nullsi ningún elemento coincide. Esto es útil para afirmar un elemento que no está presente. Esto arroja si se encuentra más de una coincidencia (use queryAllBy en su lugar).

Las queryAllBy* consultas queryAllBy devuelven una matriz de todos los nodos coincidentes para una consulta y devuelven una matriz vacía ( []) si ningún elemento coincide.

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

Entonces, para los dos específicos que mencionó, en su lugar usaría queryByTexty queryByTestId, pero estos funcionan para todas las consultas, no solo para esos dos.

Sam
fuente
2
Esto es mucho mejor que la respuesta aceptada. ¿Esta API es más nueva?
RubbelDieKatz
1
¡Gracias por las palabras amables! Esta es básicamente la misma funcionalidad que la respuesta aceptada , por lo que no creo que sea una API más nueva (pero podría estar equivocado). La única diferencia real entre esta respuesta y la aceptada es que la respuesta aceptada dice que solo hay un método que hace esto ( queryByTestId) cuando de hecho hay dos conjuntos completos de métodos, de los cuales queryByTestIdes un ejemplo específico.
Sam
Gracias, preferiría esto que configurar test-ids
Hylle
13

Tienes que usar queryByTestId en lugar de getByTestId.

Aquí un ejemplo de código en el que quiero probar si el componente con la identificación de "coche" no 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
fuente
4

getBy * arroja un error cuando no encuentra un elemento, por lo que puede verificarlo

expect(() => getByText('your text')).toThrow('Unable to find an element');
Gabriel Vasile
fuente
0

Puede usar react-native-testing-library "getAllByType" y luego verificar si el componente es nulo. Tiene la ventaja de no tener que configurar TestID, también debería funcionar con componentes de terceros

 it('should contain Customer component', () => {
    const component = render(<Details/>);
    const customerComponent = component.getAllByType(Customer);
    expect(customerComponent).not.toBeNull();
  });
Andy Rich
fuente
Este tipo de viola la premisa de no tener detalles de implementación (como el nombre del componente) en la prueba.
RubbelDieKatz