Saltar al contenido

cómo probar react-select con react-testing-library

Al fin después de tanto trabajar pudimos encontrar la respuesta de esta inconveniente que tantos lectores de nuestra web han tenido. Si tienes alguna información que compartir no dejes de dejar tu conocimiento.

Solución:

Esta tiene que ser la pregunta más frecuente sobre RTL 😀

La mejor estrategia es utilizar jest.mock (o el equivalente en su marco de prueba) para simular la selección y representar una selección HTML en su lugar.

Para obtener más información sobre por qué este es el mejor enfoque, escribí algo que también se aplica a este caso. El OP preguntó sobre una selección en Material-UI pero la idea es la misma.

Pregunta original y mi respuesta:

Porque no tienes control sobre esa interfaz de usuario. Está definido en un módulo de terceros.

Así que tienes dos opciones:

Puede averiguar qué HTML crea la biblioteca de materiales y luego usar container.querySelector para encontrar sus elementos e interactuar con ellos. Lleva un tiempo, pero debería ser posible. Después de haber hecho todo eso, debe esperar que en cada nueva versión no cambien demasiado la estructura DOM o es posible que deba actualizar todas sus pruebas.

La otra opción es confiar en que Material-UI creará un componente que funcione y que sus usuarios puedan usar. Basado en esa confianza, simplemente puede reemplazar ese componente en sus pruebas por uno más simple.

Sí, la opción uno prueba lo que ve el usuario, pero la opción dos es más fácil de mantener.

En mi experiencia, la segunda opción está bien pero, por supuesto, su caso de uso puede ser diferente y es posible que deba probar el componente real.

Este es un ejemplo de cómo podría simular una selección:

jest.mock("react-select", () => ( options, value, onChange ) => 
  function handleChange(event) 
    const option = options.find(
      option => option.value === event.currentTarget.value
    );
    onChange(option);
  
  return (
    
  );
);

Usted puede leer más aquí.

En mi proyecto, estoy usando react-testing-library y jest-dom. Me encontré con el mismo problema: después de investigar, encontré una solución basada en el hilo: https://github.com/airbnb/enzyme/issues/400

Tenga en cuenta que la función de nivel superior para el renderizado debe ser asíncrona, así como los pasos individuales.

No es necesario usar el evento de enfoque en este caso, y permitirá seleccionar múltiples valores.

Además, tiene que haber una devolución de llamada asíncrona dentro de getSelectItem.

const DOWN_ARROW =  keyCode: 40 ;

it('renders and values can be filled then submitted', async () => 
  const 
    asFragment,
    getByLabelText,
    getByText,
   = render();

  ( ... )

  // the function
  const getSelectItem = (getByLabelText, getByText) => async (selectLabel, itemText) => 
    fireEvent.keyDown(getByLabelText(selectLabel), DOWN_ARROW);
    await waitForElement(() => getByText(itemText));
    fireEvent.click(getByText(itemText));
  

  // usage
  const selectItem = getSelectItem(getByLabelText, getByText);

  await selectItem('Label', 'Option');

  ( ... )


Similar a la respuesta de @momimomo, escribí un pequeño ayudante para elegir una opción de react-select en mecanografiado.

Archivo auxiliar:

import  getByText, findByText, fireEvent  from '@testing-library/react';

const keyDownEvent = 
    key: 'ArrowDown',
;

export async function selectOption(container: HTMLElement, optionText: string) 
    const placeholder = getByText(container, 'Select...');
    fireEvent.keyDown(placeholder, keyDownEvent);
    await findByText(container, optionText);
    fireEvent.click(getByText(container, optionText));

Uso:

export const MyComponent: React.FunctionComponent = () => 
    return (