web-dev-qa-db-fra.com

Jest: Comment se moquer du composant d'exportation par défaut lorsque le même module a également nommé exportation?

J'ai un module ES6 qui exporte une classe de composant React par défaut, mais exporte également une fonction JS ordinaire en tant qu'exportation nommée. Lorsque je teste d'autres packages qui utilisent ce module, je veux me moquer de la composant exporté par défaut et fonction exportée nommée pour garder mes tests unitaires purs.

Le module ressemble à ceci:

import React, { Component } from 'react';

export default class MyComponent extends Component {
  render() {
    return <div>Hello</div>
  }
}

export function myUtilityFunction() { return 'foo' };

Je voudrais utiliser la syntaxe suivante pour simuler les exportations:

import React from 'react';
import MyComponent, { myUtilityFunction } from './module';

jest.mock('./module');
MyComponent.mockImplementation(() => 'MockComponent');
myUtilityFunction.mockImplementation(() => 'foo');

Cependant, lorsque j'essaie d'utiliser cette syntaxe, MyComponent ne semble pas se moquer lorsqu'il est utilisé dans d'autres composants. Lorsque j'essaie de me moquer de MyComponent comme ceci et de le rendre seul, il se rend nul.

Ce comportement est très étrange, car si j'utilise exactement la même syntaxe, mais que les deux importations sont des fonctions JavaScript, le mocking fonctionne comme prévu. Voir le problème StackOverflow que j'ai ouvert ici qui confirme que la syntaxe fonctionne lorsque les importations sont les deux fonctions.

Voici un repo GitHub démontrant le problème, ainsi que plusieurs solutions que j'ai essayées: https://github.com/zpalexander/jest-enzyme-problem

Vous pouvez créer le référentiel et exécuter les tests avec l'installation du fil et le test du fil

Merci!

16
bean

Je pense que le problème est que la méthode getElement de la classe ShallowWrapper doit passer une classe qui contient une méthode de rendu. Pour ce faire, votre MyComponent.mockImplementation doit se moquer plus complètement d'un constructeur de classe.

Pour plus de détails sur la façon de se moquer d'un constructeur de classe, voir la documentation Jest commençant par "mockImplementation peut également être utilisée pour se moquer des constructeurs de classe:" https://facebook.github.io/jest/docs/en/mock- function-api.html # mockfnmockimplementationfn

En utilisant la documentation Jest comme modèle, nous pouvons nous moquer du constructeur de classe MyComponent et le rendre peu profond rendu par enzyme comme ceci:

MyComponent.mockImplementation(() => {
  return {
    render: () => <div>MockComponent</div>
  };
});

Maintenant, quand getElement va chercher une méthode de rendu, il la trouvera.

Voici un Gist qui implémente cette modification sur le fichier App.mockImplementation.test.js de votre référentiel: https://Gist.github.com/timothyjellison/a9c9c2fdfb0b30aab5698dd92e901b24

3
Tim Ellison

L'autre solution n'a pas fonctionné pour moi. Voici comment j'ai fait:

  jest.mock('./module', () => ({
    __esModule: true,
    myUtilityFunction: 'myUtilityFunction',
    default: 'MyComponent'
  }));

Une autre façon de procéder:

jest.unmock('../src/dependency');

const myModule = require('../src/dependency');
myModule.utilityFunction = 'your mock'
7
Albert Olivé