web-dev-qa-db-fra.com

Utiliser Jest pour simuler un composant React avec des accessoires

J'ai un composant React qui contient d'autres composants qui dépendent de l'accès à un magasin Redux, etc., ce qui pose des problèmes lors du montage Enzyme complet. Disons une structure comme celle-ci:

import ComponentToMock from './ComponentToMock';

<ComponentToTest>
  ...some stuff
  <ComponentToMock testProp="This throws a warning" />
</ComponentToTest>

Je veux utiliser la méthode .mock() de Jest pour simuler le sous-composant, de sorte que ce ne soit pas une préoccupation pour le test.

Je suis conscient que je peux simuler un composant droit avec quelque chose comme:

jest.mock('./ComponentToMock', () => 'ComponentToMock');

Cependant, comme ce composant recevrait normalement des accessoires, React est bouleversé, avertissant que des accessoires inconnus (dans ce cas, testProp) sont passés à <ComponentToMock /> .

J'ai essayé de retourner une fonction à la place, mais vous ne pouvez pas retourner JSX (d'après ce que je pourrais dire) dans une maquette de Jest, car elle est hissée. Cela jette une erreur dans ce cas.

Alors ma question est: comment puis-je soit

a) obtient ComponentToMock ignorer les accessoires qui lui sont transmis, ou

b) retourne un composant React qui peut être utilisé pour se moquer du composant enfant que je ne crains pas de tester.

Ou ... y a-t-il un meilleur moyen?

17
Mike Hopkins

Il y a une note au bas du docs pour jest.mock() pour empêcher le comportement de levage:

Remarque: lorsque vous utilisez babel-jest, les appels à mock seront automatiquement placés en haut du bloc de code. Utilisez doMock si vous voulez éviter explicitement ce problème.

Vous pouvez ensuite faire ce que vous avez décrit: renvoyer une fonction qui constitue un talon du composant que vous n'avez pas besoin de tester.

jest.doMock('./ComponentToMock', () => {
  const ComponentToMock = () => <div />;
  return ComponentToMock;
});

const ComponentToTest = require('./ComponentToTest').default;

Il est utile de nommer le composant stub car il est rendu dans les instantanés.

17
Mike Reifman

J'ai appris un peu plus depuis que j'ai posé cette question. Voici une alternative (meilleure?) Pour gérer les composants moqueurs qui doivent être transmis aux accessoires: using module mock files.

Commencez par créer un fichier portant le même nom que le composant à simuler dans un dossier __mocks__ Sous le dossier du composant, par exemple.

.
|- /ComponentToMock.js
└- /__mocks__/ComponentToMock.js <-- create this folder/file!

Note: Il semble qu'au moment de l'écriture, le dossier doit s'appelle __mocks__ (Vous devrez créer __mocks__ Dans chaque dossier pour lequel vous devez vous moquer de composants. Si les soulignés vous contrarient, prétendez simplement qu’ils ne sont pas là;))

Ensuite, dans ce fichier fictif, vous pouvez l'écrire à votre guise, par exemple.

// This code would live in ./__mocks__/ComponentToMock.js
import React from 'react';
const ComponentToMock = ({ testProp }) => <div>A mock with '{testProp}' passed!</div>;
export default ComponentToMock;

Ensuite, dans le fichier de test, modifiez l’instruction fictive Jest en: jest.mock('./ComponentToMock');

Lorsque Jest rencontre une .mock() sans le deuxième paramètre de fonction, il recherche automatiquement un dossier __mocks__. Cependant, même si la déclaration fictive est hissée dans le composant testé, cela n’affecte pas les importations de la maquette elle-même - c’est pourquoi il est capable d’importer et de compiler un composant React!

Cela semble bien fonctionner pour les composants fictifs qui doivent être transmis, et produiraient sinon des avertissements sur les prop si une fonction nulled est retournée (mais il est parfaitement acceptable de continuer à utiliser si le composant ne reçoit pas d’accessoires). J'espère que cela aide certaines personnes.

4
Mike Hopkins