Как отменить издеваться, требовать в шутку? - PullRequest
1 голос
/ 01 апреля 2019

Я издеваюсь над библиотекой, делая это:

let helperFn;
let mock;

beforeEach(() => {
  mock = jest.fn();
  require('./helperFn').default = mock;
})

Если я делаю это в тесте, означает ли это, что отныне во всем наборе тестов эта функция по умолчанию helperFn будет связана с этим макетом?

В документации Jest я вижу, как сбросить макет, но не вижу, как удалить макет из требуемой функции. Я обеспокоен тем, что с этого теста все вызовы helperFn.default будут видеть эту ложь.

1 Ответ

0 голосов
/ 01 апреля 2019

ES6 модулей

Вот пример ES6:

helperFn.js

export default () => 'original';

code.js

import helperFn from './helperFn';

export const func = () => helperFn();

code.test.js

import * as helperFnModule from './helperFn';

import { func } from './code';

describe('helperFn mocked', () => {
  let mock;

  beforeEach(() => {
    mock = jest.spyOn(helperFnModule, 'default');
    mock.mockReturnValue('mocked');
  });

  afterEach(() => {
    mock.mockRestore();
  });

  test('func', () => {
    expect(func()).toBe('mocked');  // Success!
  });
});

describe('helperFn not mocked', () => {
  test('func', () => {
    expect(func()).toBe('original');  // Success!
  });
});

Детали

Поскольку ES6-импорт представляет собой оперативные представления об экспорте модуля, экспорт легко смоделируется, а затем восстанавливается.


Модули Node.js

Вот пример Node.js:

helperFn.js

exports.default = () => 'original';

code.js

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

exports.func = () => helperFn();

code.test.js

describe('helperFn mocked', () => {
  beforeEach(() => {
    const helperFnModule = require('./helperFn');
    helperFnModule.default = jest.fn(() => 'mocked');
  });

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

  test('func', () => {
    const { func } = require('./code');
    expect(func()).toBe('mocked');  // Success!
  });
});

describe('helperFn not mocked', () => {
  test('func', () => {
    const { func } = require('./code');
    expect(func()).toBe('original');  // Success!
  });
});

Детали

Экспорт default запоминается code.js при запуске, поэтому изменение экспорта default helperFn.js не влияет на func, если code.js равно required. Jest также кэширует модули и возвращает один и тот же модуль для нескольких вызовов require, если не вызывается jest.resetModules.

Таким образом, для модулей Node.js часто проще всего require кодировать в самом тесте и использовать jest.resetModules для сброса любых насмешек.

...