如何还原使用jest.mock()创建的模拟?

时间:2019-06-07 15:11:22

标签: unit-testing jestjs

显然,mock.mockRestore()不会还原使用jest.mock()创建的模拟的原始实现

// a.js
export default class A {}


// b.js
import A from './a';
export default class B extends A {}


// test.js
import A from './a';
import B from './b';

jest.mock('./a');
jest.mock('./b');

const b = new B();

test('instanceOf', () => {
    A.mockRestore();
    B.mockRestore();
    expect(b).toBeInstanceOf(A); // fails
});

1 个答案:

答案 0 :(得分:0)

mockFn.mockRestore仅适用于使用jest.spyOn创建的模拟函数:

const obj = {
  func: () => 'original'
}

test('func', () => {
  const mock = jest.spyOn(obj, 'func');
  mock.mockReturnValue('mocked');

  expect(obj.func()).toBe('mocked');  // Success!

  mock.mockRestore();
  expect(obj.func()).toBe('original');  // Success!
})

jest.spyOn包装了原始功能,并提供了mockRestore作为恢复原始功能的方法。


jest.mock的调用方式有所不同。

Jest接管require系统,jest.mock告诉Jest,它在需要时应返回模块模拟,而不是实际模块。

这意味着模块模拟不会包装原始模块,它会完全替换require系统中的原始模块。因此,mockRestore可以在模拟模块中的模拟函数上定义,但是调用它不会恢复原始实现。


jest.mock通常在您要为整个测试模拟整个模块时使用。

在使用ES6样式的import语句时,这特别有用,因为babel-jest会提升jest.mock调用,并且它们会在测试文件中的其他任何内容(包括任何import语句)之前运行):

import A from './a';  // <= A is already mocked...

jest.mock('./a');  // <= ...because this runs first

test('A', () => {
  // ...
}

在使用jest.mock的测试过程中,没有一种简单的方法可以还原原始模块,因为它的主要用途是为整个测试模拟模块。

如果您在同一测试中尝试同时使用模拟和原始实现,则有几种选择:

  • 使用jest.spyOn模拟一个特定功能,然后使用mockRestore还原它
  • 使用jest.doMock来避免jest.mock的举升行为……请注意,您还需要在使用require的范围内使用jest.doMock而不是顶部级import
  • 随时使用jest.requireAcutalrequire原始模块