如何撤消嘲笑要求开玩笑?

时间:2019-04-01 12:27:19

标签: javascript mocking jestjs

我这样做是在嘲笑图书馆:

let helperFn;
let mock;

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

如果我在测试中执行此操作,是否表示从现在开始在整个测试套件中,helperFn的默认功能将与该模拟程序相关联?

在Jest文档中,我看到了如何重置模拟,但没有看到如何从所需函数中删除模拟。我担心从该测试开始,所有对helperFn.default的调用都会看到该模拟。

1 个答案:

答案 0 :(得分:0)

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的{​​{1}}导出不会一次{{1}影响helperFn.js }}是funccode.js还会缓存模块,并为多个required调用返回相同的模块,除非调用了Jest

因此,对于Node.js模块,通常最简单的方法是在测试本身中使用require进行编码,并使用jest.resetModules重置任何模拟。