web-dev-qa-db-fra.com

Les moqueries exigent des déclarations avec Jest

sum.js

module.exports = function sum(a, b){
    return a + b;
};

Thing.js

var sum = require("./sum");

module.exports = class Thing {
    add(a, b){
        return sum(a, b);
    }
}

Thing.test.js

test('1 + 2 = 3', () => {
    //Arrange
    var Thing = require('./Thing');
    var thing = new Thing();

    //Act
    var result = thing.add(1, 2);

    //Assert
    expect(result).toBe(3);
});

test('sum mocked', () => {
    //Arrange
    jest.mock('./sum', () => {
        return jest.fn(() => 42);
    });

    var Thing = require('./Thing');
    var thing = new Thing();

    //Act
    var result = thing.add(1, 2);

    //Assert
    expect(result).toBe(42);
});

Comment est-ce que je peux me moquer de la somme "nécessite" la dépendance lors du test? J'obtiens l'erreur suivante.

sum mocked

    expect(received).toBe(expected)

    Expected value to be (using ===):
      42
    Received:
      3

Ce qui est intéressant si je lance chaque test individuellement avec .only, ils fonctionnent tous les deux très bien par eux-mêmes.

Dans le passé, j'ai utilisé proxyquire pour faire des choses comme ça, mais j'aimerais l'éviter si possible.

10
RoboKozo

Dans le test, j'ai ajouté

beforeEach(() =>  {
    jest.resetModules();
});

et les tests ont réussi comme prévu.

10
RoboKozo

J'ai le sentiment que la moquerie fonctionne par fichier de test. Ne me demandez pas pourquoi ¯\_ (ツ) _/¯

L'approche qui a fonctionné le mieux pour moi a été de définir des tests comme celui-ci:

// sum.test.js
//Arrange
const sum = require('./sum');

test('1 + 2 = 3', () => {
    //Act
    const result = sum(1, 2);

    //Assert
    expect(result).toBe(3);
});

Et:

// Thing.test.js
//Arrange
const Thing = require('./Thing');

// jest.mock are hoisted so you can keep imports/require on top
const sumSpy = jest.fn(() => 42);
jest.mock('./sum', () => sumSpy);

test('Thing', () => {
    const thing = new Thing();

    //Act
    const result = thing.add(1, 2);

    //Assert
    expect(sumSpy).toHaveBeenCalledTimes(1);
    expect(result).toBe(42);
});

Vous pouvez même fournir différentes implémentations simulées par test avec quelque chose comme:

sumSpy.mockImplementation(() => NaN);
3
Leonardo Moreno

Tiré des Jest Docs.

beforeEach(() => {
  jest.resetModules();
});

test('moduleName 1', () => {
  jest.doMock('../moduleName', () => {
    return jest.fn(() => 1);
  });
  const moduleName = require('../moduleName');
  expect(moduleName()).toEqual(1);
});

test('moduleName 2', () => {
  jest.doMock('../moduleName', () => {
    return jest.fn(() => 2);
  });
  const moduleName = require('../moduleName');
  expect(moduleName()).toEqual(2);
});

https://facebook.github.io/jest/docs/en/jest-object.html#jestdomockmodulename-factory-options

2
Ryan Vice