【发布时间】:2019-08-15 01:29:52
【问题描述】:
我试图在导入的 React 模块中只模拟一个函数,保持模块的其余部分不被模拟,并在所有测试的顶层执行此操作。
我正在使用新的 create-react-app 项目和单个测试来观察问题。
重现步骤:
create-react-app test- 使用提供的
src/App.test.js作为唯一的测试文件 npm run test
App.test.js
jest.mock('react', () => {
jest.dontMock('react');
const React = require('react');
const lazy = jest.fn();
return {
...React,
lazy
};
});
import * as React from 'react';
const React2 = require('react');
it('should partially mock React module', async () => {
expect(jest.isMockFunction(React.lazy)).toBe(true); // passes
expect(jest.isMockFunction(React2.lazy)).toBe(true); // fails
expect(jest.isMockFunction(require('react').lazy)).toBe(true); // fails
expect(jest.isMockFunction((await import('react')).lazy)).toBe(true); // fails
});
这里的问题似乎是jest.dontMock,因为它可以防止require 和动态import 被模拟,但仍不清楚为什么可以以这种方式模拟静态import,因为它使用require反正。这是转译文件:
"use strict";
jest.mock('react', () => {
jest.dontMock('react');
const React = require('react');
const lazy = jest.fn();
return (0, _objectSpread2.default)({}, React, {
lazy
});
});
var _interopRequireWildcard3 = require("...\\node_modules\\@babel\\runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("...\\node_modules\\@babel\\runtime/helpers/interopRequireDefault");
var _interopRequireWildcard2 = _interopRequireDefault(require("...\\node_modules\\@babel\\runtime/helpers/interopRequireWildcard"));
var _objectSpread2 = _interopRequireDefault(require("...\\node_modules\\@babel\\runtime/helpers/objectSpread"));
var React = _interopRequireWildcard3(require("react"));
const React2 = require('react');
...
这可能与 create-react-app Jest+Babel 设置有关,因为我无法使 jest.dontMock 与 vanilla Jest 和 require 一起正常工作。
为什么静态 React import 被嘲笑,而 React2 和其他的不是?里面到底发生了什么?
如何修复jest.dontMock 当前行为以在顶层部分模拟模块?
【问题讨论】:
-
我认为
require.requireActual应该做到issue 中提到的技巧。这个也不需要jest.dontMock('react')。我不知道为什么dontMock对于 import 和 require 的行为不同 - 它应该防止在这两种情况下进行模拟。 -
@AWolf 我知道 requireActual 但完全忘记了它,并且在您链接的问题中以某种方式忽略了它。确实,这就是解决方案,谢谢。如果您愿意,可以考虑提供此修复作为答案。
标签: javascript reactjs jestjs create-react-app babel-jest