Pruebas de componentes en React: qué y cómo probar con Jest y Enzyme.

Este artículo sobre las pruebas de componentes de reacción está escrito por Alona Pysarenko, ingeniera frontend de Django Stars.
Lea el artículo original en el blog de Django Stars.

Los componentes de Testing React pueden ser un desafío para principiantes y para desarrolladores experimentados que ya han trabajado con pruebas. Puede ser interesante comparar sus propios enfoques con los que usamos en nuestro proyecto. Para cubrir la base de código, debe saber qué componentes deben probarse y qué código exactamente en el componente debe cubrirse.

Durante este artículo, cubriré los siguientes temas:

  • Definir el orden correcto de las pruebas de los componentes según la estructura del proyecto.
  • Encuentre qué omitir en la cobertura de prueba (qué no probar)
  • Identificar la necesidad de la prueba de instantáneas
  • Defina qué probar en el componente y en qué orden
  • Proporcione ejemplos de códigos personalizados detallados

El artículo requiere que tenga conocimiento sobre la configuración de Jest y Enzyme. La información sobre la instalación y configuración se puede encontrar fácilmente en sus sitios web oficiales.

Suponga el siguiente caso: debe cubrir la base de código del proyecto con pruebas. ¿Con qué debería comenzar y qué debería obtener al final de la prueba? ¿100% de cobertura de prueba? Es el punto de referencia al que debe aspirar, pero en la mayoría de las situaciones no lo obtendrá.

¿Por qué? Porque no deberías probar todo el código. Descubriremos por qué y qué debería quedar fuera de las pruebas. Aún más, una cobertura de prueba del 100% no siempre garantiza que el componente se pruebe completamente. Tampoco hay garantía de que le notifique si algo ha cambiado. No se esfuerce por los porcentajes, evite escribir pruebas falsas e intente no perder los detalles del componente principal.

Definir el orden correcto de las pruebas de los componentes en función de la estructura del proyecto.

Discutamos esta pregunta en la siguiente parte de la estructura del proyecto:

Tomé el directorio compartido porque es lo más importante. Se compone de los componentes que se utilizan en varias páginas diferentes del proyecto. Son reutilizables, y normalmente son pequeños y no complejos. Si uno u otro componente falla, provocará fallas en otros lugares. Es por eso que debemos estar seguros de si se han escrito correctamente. La estructura de este directorio está dividida en varias carpetas, cada una de las cuales contiene componentes.

Cómo definir el orden correcto de las pruebas de componentes en el directorio compartido:

  • Siempre siga la regla de pasar de lo simple a lo complejo. Analice cada directorio y defina qué componentes son independientes, es decir, su representación no depende de los otros componentes. Se completan automáticamente y se pueden usar por separado como una sola unidad. De la estructura anterior, es el directorio de entradas en la carpeta de formularios. Contiene componentes de entrada para formas redux, como TextInput, SelectInput, CheckboxInput, DateInput, etc.
  • Luego, necesitamos definir los componentes auxiliares que a menudo se usan en los componentes de las entradas, pero que deben probarse aparte de ellos. Este es el directorio de utilidades. Los componentes en esta carpeta no son complicados, pero son muy importantes. Con frecuencia son reutilizables y ayudan con acciones repetidas.
  • El siguiente paso es definir qué componentes se pueden usar de forma independiente también. Si hay alguno, llévelos a prueba. Desde nuestra estructura, son los widgets, los pequeños componentes con funcionalidad simple. Serán el tercer elemento en la cola para la cobertura de la prueba.
  • Además, analice el resto de los directorios y defina componentes más complejos, que se pueden usar de forma independiente o junto con otros componentes. Es el directorio de modales en nuestro caso. Estos componentes se explicarán en detalle a continuación.
  • Los componentes más complejos se dejan hasta el final. Son el directorio y los campos de la carpeta de formularios. ¿Cómo define cuál debe probarse primero? Tomo el directorio del que los componentes ya se han utilizado en componentes probados. Por lo tanto, el componente del directorio hoc estaba presente en el componente de widgets. Es por eso que ya sé dónde y para qué se utilizan este directorio y sus componentes.
  • El último es la carpeta de campos. Contiene componentes conectados con formas redux.

El orden final de los componentes (basado en nuestro ejemplo) se verá así:

Siguiendo este orden, aumenta la complejidad de los componentes probados paso a paso. Por lo tanto, cuando se trata de operar con los componentes más complejos, ya sabe cómo se comportan los más pequeños.

No tome para probar, por ejemplo, el campo "matriz", si no está seguro de cómo probar el campo "texto". No tome componentes decorados con la forma redux si no ha probado el campo "forma" en sí.

Sea consistente en sus elecciones, no tome el primer componente que se le ocurra y cambie la lógica. Por supuesto, la estructura de su proyecto puede diferir. Puede tener otros nombres de directorio o componentes, acciones y reductores adicionales, pero la lógica de definir el orden para probar los componentes es la misma.

Definamos qué se debe omitir en la cobertura de prueba:

  • Bibliotecas de terceros. No pruebe la funcionalidad que se toma de otra biblioteca. No eres responsable de ese código. Sáltelo o imite la implementación si lo necesita para probar su código.
  • Constantes El nombre habla por sí mismo. No son cambiables. Son conjuntos de código estático que no están destinados a variar.
  • Estilos en línea (si los usa en su componente). Para probar estilos en línea, debe duplicar objetos con estilos en su prueba. Si los estilos de los objetos cambian, también debe cambiarlos en la prueba. No duplique el código de un componente en las pruebas. Nunca tendrá en cuenta cambiarlo en las pruebas. Además, su colega nunca se dará cuenta de que ha habido duplicación. En la mayoría de los casos, los estilos en línea no cambian el comportamiento del componente, por lo que no deben probarse. Puede haber una excepción si sus estilos cambian dinámicamente.
  • Cosas no relacionadas con el componente probado. Omita la cobertura con los componentes de prueba que se importaron en el componente probado. Tenga cuidado si está envuelto en otro. No pruebe el contenedor, solo analícelos y pruébelos por separado.

Entonces, ¿cómo escribes realmente las pruebas? Combino dos enfoques de prueba:

  • Prueba de instantánea
  • Prueba de lógica de componentes

Los discutiré a ambos ahora.

Cómo probar con instantáneas

Snapshot Testing es una herramienta de prueba útil en caso de que desee asegurarse de que la interfaz de usuario no haya cambiado. Al enfrentarse a esta herramienta de prueba por primera vez, es posible que tenga preguntas sobre la organización y la administración de instantáneas. El principio es muy simple, pero desafortunadamente no se ha descrito completamente en ninguna parte.

Paso 1. Escriba la prueba para el componente, y en el bloque de espera use el método .toMatchSnapshot () que crea la instantánea en sí:

it ('representar correctamente el componente de texto', () => {
    const TextInputComponent = renderer.create (). toJSON ();
    esperar (TextInputComponent) .toMatchSnapshot ();
});

Paso 2. Cuando ejecutas la prueba por primera vez en un nivel, junto con la prueba, se creará un directorio llamado __snapshots__ con el archivo autogenerado dentro con la extensión.snap.

La instantánea se ve así:

// Jest Snapshot v1, https://goo.gl/fbAQLP
exporta [`Render TextInput correctamente componente 1`] =`

`;

Paso 3. Empuje la instantánea en el repositorio y guárdela junto con la prueba.

Si se ha cambiado el componente, solo necesita actualizar la instantánea con —updateSnapshot flag o usar la forma abreviada u flag.

Entonces, se crea la instantánea: ¿cómo funciona?

Consideremos dos casos:

1. El componente ha cambiado

  • Ejecutar pruebas
  • Se crea una nueva instantánea, se compara con la instantánea generada automáticamente almacenada en el directorio __snapshots__
  • Las pruebas fallaron porque la instantánea es diferente

2. El componente no ha cambiado

  • Ejecutar pruebas
  • Se crea una nueva instantánea, se compara con la instantánea generada automáticamente almacenada en el directorio __snapshots__
  • Pruebas aprobadas porque la instantánea es idéntica

Todo está bien cuando probamos un componente pequeño sin lógica (solo renderizado UI). Pero como muestra la práctica, no existen tales componentes en proyectos reales. Si existen, son pocos.

¿Hay suficientes instantáneas para la prueba de componentes completos?

Instrucciones principales para la prueba de componentes

1. Un componente debe tener solo una instantánea.

Si una instantánea falla, lo más probable es que las otras también lo hagan. No cree y almacene un montón de instantáneas innecesarias que obstruyan el espacio y confundan a los desarrolladores que leerán sus pruebas después de usted.

Por supuesto, hay excepciones cuando necesita probar el comportamiento de un componente en dos estados: por ejemplo, en el estado del componente antes de abrir la ventana emergente y después de abrirlo.

Sin embargo, incluso esta variante siempre se puede reemplazar por esta: la primera prueba almacena el estado predeterminado del componente sin la ventana emergente en la instantánea, y la segunda prueba simula el evento y verifica la presencia de una clase en particular. De esta manera, puede evitar fácilmente la creación de varias instantáneas.

2. Prueba de accesorios

Como regla, divido la prueba de los accesorios en dos pruebas:

  • En primer lugar, verifique el renderizado de los valores de utilería predeterminados. Cuando se representa el componente, espero que un valor sea igual a defaultProps en caso de que este accesorio tenga defaultProps.
  • En segundo lugar, verifique el valor personalizado del accesorio. Establezco mi propio valor y espero que se reciba después de la representación del componente.

3. Prueba de tipos de datos

Para probar qué tipo de datos vienen en los accesorios o qué tipo de datos se obtienen después de ciertas acciones, podemos usar la biblioteca especial jest-extended (Matchers adicionales de Jest), que tiene un conjunto extendido de coincidencias que están ausentes en el Broma. Con esta biblioteca, probar los tipos de datos es mucho más fácil y divertido.

Probar tipos, por otro lado, es una pregunta contradictoria. Algunos desarrolladores pueden argumentar en contra de las pruebas de proptypes porque es un paquete de terceros y no debe probarse. Aún así, insisto en probar los tipos de componentes porque no pruebo la funcionalidad del paquete en sí. En cambio, solo me aseguro de que los prototipos sean correctos. El tipo de datos es una parte de programación muy importante y no se debe omitir.

4. Prueba de eventos

Después de crear una instantánea y cubrir los accesorios con pruebas, puede estar seguro de que el componente se representará correctamente. Pero esto no es suficiente para una cobertura total en caso de que tenga eventos en el componente.

Puede verificar el evento de varias maneras. Los más utilizados son:

  • simulacro de evento => simularlo => esperar evento fue llamado
  • evento simulado => simular evento con parámetros => esperar evento se llamó con parámetros pasados
  • pasar los accesorios necesarios => componente de representación => simular evento => esperar un cierto comportamiento en el evento llamado

5. Condiciones de prueba

Muy a menudo puede tener condiciones para la salida de una clase en particular, renderizar una determinada sección del código, transferir los accesorios necesarios, etc. No se olvide de esto, porque con los valores predeterminados, solo una rama pasará la prueba, mientras que la segunda permanecerá sin probar.

En componentes complejos con cálculos y muchas condiciones, puede pasar por alto algunas ramas. Para asegurarse de que todas las partes del código estén cubiertas por pruebas, use una herramienta de cobertura de prueba y verifique visualmente qué ramas están cubiertas y cuáles no.

6. Estado de prueba

Para verificar el estado, en la mayoría de los casos, es necesario escribir dos pruebas:

  • El primero verifica el estado actual.
  • El segundo verifica el estado después de llamar a un evento. Procesar componente => llamar a la función directamente en la prueba => verificar cómo ha cambiado el estado. Para llamar a la función del componente, necesita obtener una instancia del componente y solo luego llamar a sus métodos (el ejemplo se muestra en la próxima prueba).

Después de recorrer esta lista de instrucciones, su componente estará cubierto del 90 al 100%. Dejo un 10% para casos especiales que no se describieron en el artículo, pero que pueden aparecer en el código.

Ejemplos de pruebas

Pasemos a ejemplos y cubramos componentes con pruebas como hemos descrito arriba paso a paso.

1. Prueba de un componente a partir de formularios / entradas.

Tome un componente del directorio de formularios / entradas. Deje que sea DateInput.js, el componente para el campo datepicker.

Listado de código para el componente probado: DateInput.js
Parece:

El componente DateInput usa la biblioteca react-datepicker, con dos utilidades:

  • valueToDate (convierte el valor a la fecha)
  • dateToValue (convierte la fecha en valor)

El paquete es para manipular con date y PropTypes es para verificar los accesorios de React.

De acuerdo con el código del componente, podemos ver la lista de accesorios predeterminados que ayudan a que el componente se renderice:

const defaultProps = {
    inputClassName: 'input-custom',
    meses Mostrados: 1,
    dateFormat: 'DD.MM.YYYY',
    showMonthYearsDropdowns: false,
    minDate: moment ()
};

Todos los accesorios son apropiados para crear la instantánea, excepto uno: minDate: moment (). moment () nos dará la fecha actual cada vez que ejecutamos la prueba y la instantánea fallará porque almacena la fecha desactualizada. La solución es burlarse de este valor:

const defaultProps = {
    minDate: moment (0)
}

Necesitamos minDate prop en cada componente renderizado. Para evitar la duplicación de accesorios, creo HOC que recibe defaultProps y devuelve un componente bonito:

importar TestDateInput desde '../DateInput';
const DateInput = (accesorios) =>
    ;

No se olvide de la zona horaria de momento, especialmente si sus pruebas serán ejecutadas por desarrolladores de otro país en una zona horaria diferente. Recibirán el valor simulado, pero con un cambio de zona horaria. La solución es establecer una zona horaria predeterminada:

const moment = require.requireActual ('moment-timezone'). tz.setDefault ('America / Los_Angeles')

Ahora el componente de entrada de fecha está listo para probar:

1.Cree primero la instantánea:

it ('representar correctamente el componente de fecha', () => {
    const DateInputComponent = renderer.create (). toJSON ();
    esperar (DateInputComponent) .toMatchSnapshot ();
});

2.Apoyos de prueba:

Mira a través de los accesorios y encuentra los más importantes. El primer accesorio para probar es showMonthYearsDropdowns. Si se establece en verdadero, se muestra el menú desplegable por mes y años:

it ('se muestran las listas desplegables de mes y año', () => {
    apoyos const = {
            showMonthYearsDropdowns: true
        },
        DateInputComponent = mount ().find('.datepicker ');
    expect (DateInputComponent.hasClass ('react-datepicker-hide-month')). toEqual (true);
});

Probar el valor de apoyo nulo. Esta verificación es necesaria para garantizar que el componente se procese sin un valor definido:

it ('ingresa la fecha correctamente con valor nulo', () => {
    apoyos const = {
            valor: nulo
        },
        DateInputComponent = mount ();
    esperar ((DateInputComponent) .prop ('valor')). toEqual (nulo);
});

3. Probar los tipos de valor, la fecha se espera que sea una cadena:

it ('verifique el tipo de valor', () => {
    apoyos const = {
            valor: '10 .03.2018 '
        },
        DateInputComponent = mount ();
    esperar (DateInputComponent.prop ('valor')). toBeString ();
});

4. Eventos de prueba:

Primero, verifique el evento onChange.

  • simulacro de devolución de llamada
  • componente de entrada de fecha de procesamiento
  • simular evento de cambio con nuevo valor objetivo
  • y finalmente verifique que el evento onChange se haya llamado con un nuevo valor.
it ('comprueba la devolución de llamada onChange', () => {
    const onChange = jest.fn (),
        accesorios = {
            valor: '20 .01.2018 ',
            onChange
        },
        DateInputComponent = mount ().find('input ');
    DateInputComponent.simulate ('change', {target: {value: moment ('2018-01-22')}});
    esperar (onChange) .toHaveBeenCalledWith ('22 .01.2018 ');
});

A continuación, asegúrese de que la ventana emergente datepicker se abre después de hacer clic en la entrada de fecha. Para eso, busque date input => simulate click event => y espere una ventana emergente cuando la clase .react-datepicker esté presente.

it ('check DatePicker popup open', () => {
    const DateComponent = mount (),
        dateInput = DateComponent.find ("input [type = 'text']");
    dateInput.simulate ('clic');
    esperar (DateComponent.find ('. react-datepicker')). toHaveLength (1);
});

Listado completo de pruebas: DateInput.test.js

2. Pruebas de utilidad:

Listado de código para la utilidad probada: valueToDate.js

El propósito de esta utilidad es transformar un valor en una fecha con un formato personalizado.

En primer lugar, analicemos la utilidad dada y definamos los casos principales para la prueba:

  1. De acuerdo con el propósito de esta utilidad, transforma el valor, por lo que debemos verificar este valor:
  • En caso de que el valor no esté definido: debemos asegurarnos de que la utilidad no devolverá una excepción (error).
  • En caso de que se defina el valor: debemos verificar que la utilidad devuelva la fecha del momento.

2. El valor devuelto debe pertenecer a la clase de momento. Por eso debería ser una instancia de momento.

3. El segundo argumento es dateFormat. Configúrelo como constante antes de las pruebas. Es por eso que se aprobará en cada prueba y valor de retorno de acuerdo con el formato de fecha. ¿Deberíamos probar dateFormat por separado? Supongo que no. Este argumento es opcional: si no establecemos dateFormat, la utilidad no se interrumpirá y solo devolverá la fecha en el formato predeterminado. Es un momento de trabajo, no deberíamos probar bibliotecas de terceros. Como mencioné antes, no debemos olvidarnos de la zona horaria de momento; Es un punto muy importante, especialmente para los desarrolladores de diferentes zonas horarias.

Codifiquemos:

  1. Escribe la prueba para el primer caso. Cuando no tenemos un valor, está vacío.
const format = 'DD.MM.YYYY';
it ('render valueToDate utility with empty value', () => {
    const value = valueToDate ('', formato);
    esperar (valor) .toEqual (nulo);
});

2. Compruebe si el valor está definido.

const date = '21 .11.2015 ',
      formato = "DD.MM.AAAA";
it ('render valueToDate utilidad con valor definido', () => {
    const value = valueToDate (fecha, formato);
    esperar (valor) .toEqual (momento (fecha, formato));
});

3. Compruebe si el valor pertenece a la clase de momento.

const date = '21 .11.2015 ',
    format = 'DD.MM.YYYY';
it ('el valor de verificación es instancia de momento', () => {
    const value = valueToDate (fecha, formato);
    esperar (valor instancia de momento) .toBeTruthy ();
});

Listado completo de pruebas: valueToDate.test.js

3. Pruebas de widgets

Para las pruebas de widgets, tomé un componente giratorio.

Listado de código para el widget probado: Spinner.js

Se ve como esto:

El spinner no se requiere en la explicación, ya que casi todos los recursos web tienen este componente.

Entonces, si vamos a escribir pruebas:

  1. Primer paso: crear una instantánea:
it ('render correctamente componente Spinner', () => {
   const SpinnerComponent = mount ();
   esperar (SpinnerComponent) .toMatchSnapshot ();
});

2. Prueba de accesorios:

Primero, miramos el título de utilería predeterminado y verificamos si se muestra correctamente.

it ('verifica el título del accesorio por defecto', () => {
 const SpinnerComponent = mount ();
    esperar (SpinnerComponent.find ('p'). text ()). toEqual ('Espere');
});

Luego verificamos el título del accesorio personalizado. Necesitamos verificar que devuelva el accesorio correctamente definido. Eche un vistazo al código, el título está envuelto en la utilidad rawMarkup y sale con la ayuda de la propiedad peligrosamente SetInnerHTML.

Listado de código para la utilidad rawMarkup:

función predeterminada de exportación rawMarkup (plantilla) {
    return {__html: template};
}

¿Necesitamos incluir pruebas para rawMarkup en el componente giratorio? No, es una utilidad separada y debe probarse aparte de la ruleta. No nos importa cómo funciona, solo necesitamos saber que el título de propiedad devuelve el resultado correcto.

Aclaración: La razón para usar la propiedad dangerouslySetInnerHTML es la siguiente. Nuestro sitio es multilingüe, del cual es responsable el equipo de marketing de traducciones. Pueden traducirlo simplemente con una combinación de palabras o incluso decorarlo con las etiquetas HTML, como , , o incluso cortar texto con las listas

    ,
      . No sabemos con certeza cómo traducen y decoran el texto. Solo necesitamos renderizar correctamente todo esto.

      Combiné dos casos de prueba principales en una prueba:

      • devolver el título de utilería personalizado correcto
      • renderizar el título del accesorio correctamente con etiquetas HTML
      it ('comprueba el título del accesorio con etiquetas html', () => {
          apoyos const = {
                  título: ' Por favor, espere '
              },
              SpinnerComponent = mount ();
          esperar (SpinnerComponent.find ('p'). text ()). toEqual ('Espere');
      });

      Toma el siguiente subtítulo de utilería. Es opcional y es por eso que no tiene un accesorio predeterminado, así que omita el paso con accesorios predeterminados y pruebe accesorios personalizados:

      • Verifique que el texto en subtitle prop se represente correctamente:
      apoyos const = {
              subtítulo: 'izquierda 1 minuto'
          },
          SpinnerComponent = mount ();
      it ('procesar texto correcto', () => {
          esperar (SpinnerComponent.find ('p'). at (1) .text ()). toEqual (props.subTitle);
      });

      Sabemos que el subtítulo es opcional. Es por eso que debemos verificar si no se procesa con accesorios predeterminados, de acuerdo con el marcado de corte. Simplemente verifique el número de etiquetas

      :

      it ('comprobar que el subtítulo no se representa', () => {
        const SpinnerComponent = mount ();
          esperar (SpinnerComponent.find ('p'). length) .toEqual (1);
      });

      3.Tipo de accesorios de prueba:

      • Para el título de propiedad se espera que sea una cadena:
      it ('comprobar el tipo de accesorio para el título es string', () => {
          apoyos const = {
                  título: 'Espera'
              },
              SpinnerComponent = mount ();
          esperar (SpinnerComponent.find ('p'). text ()). toBeString ();
      });
      • Para subtitle prop también se espera que sea string:
      apoyos const = {
              subtítulo: 'izquierda 1 minuto'
          },
          SpinnerComponent = mount ();
      it ('type for subTitle is string', () => {
          esperar (SpinnerComponent.find ('p'). at (1) .text ()). toBeString ();
      });

      Listado completo de pruebas: Spinner.test.js

      4. Prueba de modalidades (ModalWrapper.js y ModalTrigger.js)

      Parece:

      Cómo probar modales

      En primer lugar, quiero explicar cómo se organizan los modales en nuestro proyecto. Tenemos dos componentes: ModalWrapper.js y ModalTrigger.js.

      ModalWrapper es responsable del diseño emergente. Contiene el contenedor modal, el botón "cerrar", el título modal y el cuerpo.

      ModalTrigger es responsable del manejo modal. Incluye el diseño ModalWrapper y contiene eventos para el control del diseño modal (acciones de apertura y cierre).

      Revisaré cada componente por separado:

      1. Listado de códigos para el componente probado: ModalWrapper.js

      Codifiquemos:

      Primero, el ModalWrapper recibe el componente y lo muestra dentro. En primer lugar, verifique que ModalWrapper no falle sin el componente. Crea una instantánea con accesorios predeterminados:

      it ('sin componente', () => {
          const ModalWrapperComponent = superficial ();
          esperar (ModalWrapperComponent) .toMatchSnapshot ();
      });

      El siguiente paso es simular su condición real con la representación de componentes pasada a través de accesorios:

      it ('con componente', () => {
         apoyos const = {
                 componente: () => {}
              },
              ModalWrapperComponent = superficial ();
          esperar (ModalWrapperComponent) .toMatchSnapshot ();
      });

      Prueba de accesorios

      Recibiendo prop de nombre de clase personalizado:

      it ('render nombre de clase correcto', () => {
          apoyos const = {
                  modalClassName: 'nombre-clase-personalizado'
              },
              ModalWrapperComponent = superficial ().find('Modal ');
              esperar (ModalWrapperComponent.hasClass ('nombre-clase-personalizado')). toEqual (verdadero);
      });

      Recibiendo un título personalizado:

      it ('render title correcto', () => {
          apoyos const = {
                 título: 'Título modal'
             },
             ModalWrapperComponent = shallow ().find('ModalTitle ');
          esperar (ModalWrapperComponent.props (). children) .toEqual ('Título modal');
      });

      Recibiendo el espectáculo correcto:

      it ('verificar valor de apoyo', () => {
              apoyos const = {
                     espectáculo: verdadero
                 },
                 ModalWrapperComponent = superficial ().find('Modal ');
              esperar (ModalWrapperComponent.props (). show) .toEqual (verdadero);
          });

      Probar tipos

      • Para mostrar utilería
      it ('check prop type', () => {
          apoyos const = {
                 espectáculo: verdadero
              },
              ModalWrapperComponent = superficial ().find('Modal ');
          esperar (ModalWrapperComponent.props (). show) .toBeBoolean ();
      });
      • Para el apoyo deHide
      it ('render correcto enHide prop type', () => {
          apoyos const = {
                  enHide: () => {}
              },
              ModalWrapperComponent = superficial ().find('Modal ');
          esperar (ModalWrapperComponent.props (). onHide) .toBeFunction ();
      });
      • Para componente prop
      it ("representa el tipo de accesorio de componente correcto", () => {
         apoyos const = {
                 componente: () => {}
             },
             ModalWrapperComponent = mount ();
         esperar (ModalWrapperComponent.props (). componente) .toBeFunction ();
      });

      Listado completo de pruebas: ModalWrapper.test.js

      2. Listado de códigos para el componente probado: ModalTrigger.js

      El contenedor modal se ha cubierto con una prueba. La segunda parte es cubrir el componente del disparador modal.

      Descripción general del componente: se basa en el estado activado que indica la visibilidad de ModalWrapper. Si se alterna: falso, la ventana emergente está oculta, de lo contrario es visible. La función open () abre la ventana emergente en el elemento hijo. El evento de clic y la función close () ocultan la ventana emergente en el botón representado en el ModalWrapper.

      Creación de instantáneas:

      it ('renderizar el componente ModalTrigger correctamente', () => {
          const ModalTriggerComponent = superficial ( 
      );     esperar (ModalTriggerComponent) .toMatchSnapshot (); });

      ¿Deberíamos probar ModalTrigger con el renderizado de componentes? No, porque el componente se representará dentro del componente ModalWrapper. No depende del componente probado. Ya estaba cubierto con pruebas en las pruebas ModalWrapper.

      Prueba de accesorios:

      Tenemos un hijo de utilería y queremos estar seguros de que solo tenemos un hijo.

      it ('asegúrese de tener solo un hijo (elemento de control)', () => {
          esperar (ModalTriggerComponent.findWhere (node ​​=> node.key () === 'modal-control'). length) .toEqual (1);
      });

      Probar tipos:

      El accesorio de niño debe ser un objeto, así que verifique esto en la próxima prueba:

      const ModalTriggerComponent = mount ( 
      );
      it ('check children prop type', () => {
            esperar (ModalTriggerComponent.props (). children) .toBeObject ();
      });

      Una parte importante del componente ModalTrigger es verificar los estados.

      Tenemos dos estados:

      • Ventana emergente abierta. Para saber que el modal está abierto, necesitamos verificar su estado. Para esto, llame a la función abierta desde la instancia del componente y espere que el estado activado sea verdadero.
      it ('comprueba que el modal está abierto', () => {
          evento const = {
              preventDefault: () => {},
              stopPropagation: () => {}
          };
          ModalTriggerComponent.instance (). Open (event);
          esperar (ModalTriggerComponent.state (). toggled) .toBeTruthy ();
      });
      • El popup está cerrado. Se prueba al revés, el estado activado debe ser falso.
      it ('comprueba que el modal está cerrado', () => {
         ModalTriggerComponent.instance (). Close ();
         esperar (ModalTriggerComponent.state (). toggled) .toBeFalsy ();
      });

      Listado completo de pruebas: ModalTrigger.test.js

      Ahora los modales están completamente probados. Un consejo para probar los componentes que dependen unos de otros: primero revise los componentes y escriba el plan de prueba, defina lo que necesita probar en cada componente, verifique los casos de prueba para cada componente y asegúrese de que no Repita el mismo caso de prueba en ambos componentes. Analice cuidadosamente las posibles y óptimas variantes para la cobertura de prueba.

      5. Prueba de HOC (componente de orden superior)

      Las dos últimas partes (HOC y pruebas de campos de formulario) están interconectadas. Me gustaría compartir con ustedes cómo probar el diseño de campo con su HOC.

      Aquí hay una explicación de qué es BaseFieldLayout, por qué necesitamos este componente y dónde lo usamos:

      • BaseFieldLayout.js es el contenedor para los componentes de entrada de formulario como TextInput, CheckboxInput, DateInput, SelectInput, etc. Sus nombres terminan en -Input porque usamos el paquete redux-form y estos componentes son los componentes de entrada para reducir la lógica de forma.
      • Necesitamos BaseFieldLayout para crear el diseño de los componentes de los campos de formulario, es decir, la etiqueta de representación, información sobre herramientas, prefijos (moneda, abreviaturas de metros cuadrados, etc.), iconos, errores, etc.
      • Lo usamos en BaseFieldHOC.js para ajustar el inputComponent en el diseño del campo y conectarlo con el formulario redux con la ayuda del componente .

      Listado de código para el componente probado: BaseFieldHOC.js

      Es un HOC que recibe el componente de entrada de formulario y devuelve el componente, conectado con redux-form.

      Analizando el HOC:

      • Este componente recibe solo un accesorio, componente. En primer lugar, necesito crear este componente y envolverlo en BaseFieldHOC.
      • Luego, necesito decorar el HOC envuelto con forma redux para poder conectar el campo con forma redux.
      • Renderice este campo dentro del componente React Redux para que la tienda esté disponible para el componente probado. Para burlarse de la tienda, solo haga:
      const store = createStore (() => ({}));

      Ahora, antes de cada prueba, necesito hacer lo siguiente:

      deje BaseFieldHOCComponent;
      beforeEach (() => {
          const TextInput = () => {return 'entrada de texto'; },
              BaseFieldHOCWrapper = BaseFieldHOC (TextInput),
              TextField = reduxForm ({formulario: 'testForm'}) (BaseFieldHOCWrapper);
          BaseFieldHOCComponent = renderer.create (
              
                  
              
          ) .toJSON ();
      });

      Después de eso, el componente está listo para probar:

      1. Crear instantánea:
      it ('render correctamente componente', () => {
          esperar (BaseFieldHOCComponent) .toMatchSnapshot ();
      });

      2. Asegúrese de que el componente de entrada esté envuelto en BaseFieldLayout después de renderizar:

      it ('comprobar que el componente de entrada está envuelto en BaseFieldLayout', () => {
          esperar (BaseFieldHOCComponent.props.className) .toEqual ('form-group');
      });

      Eso es todo, el HOC está cubierto. La parte más complicada en la prueba de componentes conectados con redux-form es preparar el campo (decorar con redux form y configurar la tienda). El resto es fácil, solo siga las instrucciones y nada más.

      Listado completo de pruebas: BaseFieldHOC.test.js

      6. Formularios / pruebas de campo

      El campo HOC está cubierto con pruebas para que podamos pasar al componente BaseFieldLayout.

      Listado de código para el componente probado: BaseFieldLayout.js

      Codifiquemos BaseFieldLayout.js y escriba las pruebas de acuerdo con las instrucciones anteriores:

      1. En primer lugar, cree una instantánea.

      Este componente no se representará sin defaultProps:

      • inputComponent
      • Los accesorios proporcionados por redux-form: input y metaobjetos. Entrada con nombre de propiedad y meta con error de propiedades y tocado:
      const defaultProps = {
         meta: {
              tocado: nulo,
              error: nulo
          },
          entrada: {
              nombre: 'nombre-campo'
          },
          inputComponent: () => {return 'caso de prueba'; }
      }

      Para usar defaultProps en cada contenedor probado, haga lo siguiente:

      importar TestBaseFieldLayout desde '../BaseFieldLayout';
      const BaseFieldLayout = (props) => ;

      Ahora estamos listos para crear una instantánea:

      it ('render correctamente componente BaseFieldLayout', () => {
          const BaseFieldLayoutComponent = renderer.create (). toJSON ();
          esperar (BaseFieldLayoutComponent) .toMatchSnapshot ();
      });

      2. Prueba de accesorios:

      Este componente tiene muchos accesorios. Mostraré ejemplos de varios, y el resto se probará por analogía.

      • Asegúrese de que el ícono se represente correctamente
      it ('render correctamente icon prop', () => {
          apoyos const = {
                  icono: 
              },
              BaseFieldLayoutComponent = mount ();
              esperar (BaseFieldLayoutComponent.find ('span'). hasClass ('icon-exclamation')). ​​toBeTruthy ();
      });
      • Asegúrese de que el contenido de información sobre herramientas se muestra junto a la etiqueta
      apoyos const = {
              labelTooltipContent: 'información sobre herramientas para la etiqueta'
          },
          BaseFieldLayoutComponent = mount ();
      it ('comprobar prop se representa', () => {
         esperar (BaseFieldLayoutComponent.find ('span'). hasClass ('tooltip-icon')). ​​toBeTruthy ();
      });
      • Prueba de campo Link prop
      • Asegúrese de que fieldLink sea nulo por defecto
      it ('comprobar prop es nulo por defecto', () => {
          const BaseFieldLayoutComponent = superficial ();
          esperar (BaseFieldLayoutComponent.props (). fieldLink) .toBe (nulo);
      });
      • Asegúrese de que fieldLink se representa correctamente con un valor personalizado

      3. Errores de prueba:

      it ('comprueba si el campo tiene error', () => {
          apoyos const = {
                  meta: {
                      tocado: cierto,
                      error: 'Este campo es obligatorio'
                  }
              },
              BaseFieldLayoutComponent = mount ();
          esperar (BaseFieldLayoutComponent.find ('. error')). toHaveLength (1);
      });

      Listado completo de pruebas: BaseFieldLayout.test.js

      Línea de fondo

      Ahora ya sabe cómo realizar pruebas de cobertura completa de componentes según la estructura del proyecto. Desde mi propia experiencia, traté de explicar qué es necesario probar, en qué orden y qué puede omitir en la cobertura de la prueba. Además, demostré ejemplos de varios componentes de prueba y descubrí la secuencia de cobertura de la base de código.

      Espero que encuentre útil este artículo y comparta sus respuestas. Gracias por leer.

      Si encuentra útil esta publicación, toque el botón a continuación :)