用Java的Jest模拟整个模块

oop*_*nou 6 javascript jestjs

我搜索了很长时间,以开玩笑地模拟任何模块(就像rewire一样)。我终于设法做到了,它就像一个魅力:

jest.mock('common/js/browser-utils', () => ({
    openBrowser: jest.fn()
}));
const { openBrowser: openBrowserSpy } = jest.requireMock(
    'common/js/browser-utils'
);
Run Code Online (Sandbox Code Playgroud)

但是我想知道是否还有另一种快速的方法?我看到了该genMockFromModule方法,但是我从未使它起作用(也许不是这种用法。)

我要的是简单的:嘲讽由一个模块jest.fn()(或任何自动机制),然后能够访问此jest.fn()在我的测试中(此处openBrowserSpy),以expect(assertions)在其上

Bri*_*ams 8

您可以使用jest.mock以下命令自动模拟模块:

jest.mock('common/js/browser-utils');
Run Code Online (Sandbox Code Playgroud)

可以通过更好地描述“自动模拟版本”的含义来改进文档,但发生的情况是Jest在用空模拟函数替换实现的同时保持模块的 API 表面相同。

完整示例

浏览器utils.js

export const openBrowser = () => { /* do something */ };
Run Code Online (Sandbox Code Playgroud)

代码.js

import { openBrowser } from './browser-utils';

export const func = () => {
  /* do stuff */
  openBrowser();
  /* do other stuff */
}
Run Code Online (Sandbox Code Playgroud)

代码.test.js

jest.mock('./browser-utils');  // create an auto-mock of the module

import { openBrowser } from './browser-utils';  // openBrowser is already an empty mock function
import { func } from './code';

test('func', () => {
  func();
  expect(openBrowser).toHaveBeenCalled();  // Success!
});
Run Code Online (Sandbox Code Playgroud)

奖励:模拟单功能

要模拟单个函数,您可以jest.spyOn像这样使用:

import * as browserUtils from './browser-utils';
import { func } from './code';

test('func', () => {
  const spy = jest.spyOn(browserUtils, 'openBrowser');
  spy.mockImplementation();  // replace implementation with empty mock function (optional)
  func();
  expect(spy).toHaveBeenCalled();  // Success!
});
Run Code Online (Sandbox Code Playgroud)

  • @oopinou 不客气!...实际上在这种情况下,`jest.mock` 是否先出现并不重要,因为 [`babel-jest` hoists 调用 `jest.mock` 到代码块的顶部](https:/ /jestjs.io/docs/en/jest-object.html#jestdomockmodulename-factory-options) 所以任何 `jest.mock` 调用*总是*先发生。 (2认同)