web-dev-qa-db-fra.com

Jestjs comment tester la fonction appelée dans une autre fonction

Pour les tests, j'utilise jest et react-test-renderer. Cela devrait être simple à tester, mais j'ai du mal à trouver le bon exemple. J'ai essayé de faire quelque chose comme ça (en général, je garde les fonctions dans des fichiers séparés):

utils.js

export const childFunction = () => 'something';    
const parentFunction = () => childFunction();
export default parentFunction;

utils.test.js

import parentFunction from './utils.js';


it('childFunction should be called', () => {
 const childFunction = jest.fn();
 parentFunction();
 expect(childFunction).toBeCalled();
})

Le fragment const childFunction = jest.fn (); ne fonctionnera certainement pas. Lors de l'appel, le corps de parentFunction ne se soucie que de sa propre portée. Mais cela ne fonctionnera pas non plus si j'importe childFunction et fais jest.mock (childFunction), car jest.mock a besoin d'une chaîne, d'une URL vers un module, et non de la fonction elle-même.

L'exemple ci-dessus ne fonctionne pas et je recherche une alternative. Cependant, cela fonctionne après le rendu du composant avec ShallowRenderer. Et j'aimerais obtenir un comportement similaire avec une fonction imbriquée dans une autre fonction.

class Component extends React.Component {
 componentDidMount() {parentFunction()}
 render() {...}
}

const renderer = new ShallowRenderer();
describe("testing parentFunction", () => {
  renderer.render(<Component/>);
  it("parentFunction should be called", () => {
    expect(parentFunction).toBeCalled();
  });
});
6
Dune

Il n'y a aucun moyen d'espionner l'appel de fonction si une fonction n'est pas appelée comme méthode objet.

Comme expliqué dans cette réponse , en raison du fonctionnement des modules ES, il est possible d'espionner ou de se moquer d'une fonction uniquement si elle a été exportée à partir d'un module et utilisée dans un autre module. De cette façon, il peut être espionné sur le module * objet, ou se moquer de jest.mock.

Si ce n'est pas le cas, il doit être testé indirectement:

expect(childFunction()).toBe('something');
expect(parentFunction()).toBe('something');
3
Estus Flask

je ne sais pas si cela vous aidera, mais cela pourrait vous donner des idées.

tout d'abord, l'exemple ci-dessus:

// this needs to be stubbed
// const childFunction = () => 'something';
const childFunction = jest.fn();

const parentFunction = () => childFunction();

it('childFunction should be called', () => {
    parentFunction();
    expect(childFunction).toHaveBeenCalled();
}

il s'agit d'un exemple quelque peu artificiel car il est peu probable que childFunction soit exporté, vous ne pouvez donc pas y avoir de référence et le simuler/le stub.

une solution de contournement que vous auriez serait de le déplacer dans sa propre méthode

class Component extends React.Component {
  componentDidMount() {
    this.parentFunction();
  }
  parentFunction() {
    parentFunction(); // from elsewhere
  }
  render() {...}
}

Cela vous permet de créer une crevaison et d'espionner la proto du composant.

par exemple

const spy = jest.spyOn(Component.prototype, 'parentFunction');

// ... mount so lifecycle runs... 
expect(spy).toHaveBeenCalled(); // and clear the spy mocks after!

il peut être préférable de se moquer du module

par exemple, vous avez utils.js utilisé par votre composant qui fait:

export function parentFunction(){ console.log('parent'); }

component.js fait:

import { parentFunction } from './utils';

vous pourriez dans vos tests faire:

const utils = require('./utils');
utils.parentFunction = jest.fn();
import Component from './component';
// later
expect(utils.parentFunction).toHaveBeenCalled();

comme vous pouvez le voir, de nombreuses façons de procéder, bien que je ne sois pas sûr de la valeur de ce test, vous devriez probablement tester la sortie/la fonctionnalité du composant plutôt qu'il ne l'avait appelé, en exécutant quelque chose sur componentDidMount est une donnée et ne se briserait que si quelqu'un se convertissait en fonctionnel ou modifiait le nom du cycle de vie.

2