Est*_*ask 8 javascript reactjs jestjs babel-jest create-react-app
我试图在导入的 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
});
Run Code Online (Sandbox Code Playgroud)
这里的问题似乎是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');
...
Run Code Online (Sandbox Code Playgroud)
这可能与 create-react-app Jest+Babel 设置有关,因为我无法jest.dontMock
使用 vanilla Jest 和require
.
为什么静态React
导入被嘲笑React2
,而其余的则不是?里面究竟发生了什么?
如何jest.dontMock
修复当前行为以在顶层部分模拟模块?
React.lazy
一个简单的解决方案是在以下位置进行模拟setupTest.js
:
import React from 'react';
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
configure({ adapter: new Adapter() });
jest.spyOn(React.lazy);
Run Code Online (Sandbox Code Playgroud)
每个测试文件的任何后续require/imports
部分都react
将被部分模拟。
工作示例: https: //github.com/mattcarlotta/react-lazy-mocked(我不使用create-react-app
,但jest
可以按照与我相同的方式进行设置)
安装:
git clone git@github.com:mattcarlotta/react-lazy-mocked.git
cd react-lazy-mocked
yarn install
yarn test
根/__tests__/root.test.js
import React from 'react';
import App from '../index.js';
const React2 = require('react');
describe('App', () => {
const wrapper = mount(<App />);
it('renders without errors', () => {
const homeComponent = wrapper.find('.app');
expect(homeComponent).toHaveLength(1);
});
it('should partially mock React module', async () => {
expect(jest.isMockFunction(await require('react').lazy)).toBe(true); // eslint-disable-line global-require
expect(jest.isMockFunction(React)).toBe(false);
expect(jest.isMockFunction(React.lazy)).toBe(true);
expect(jest.isMockFunction(React2)).toBe(false);
expect(jest.isMockFunction(React2.lazy)).toBe(true);
});
it('should no longer be partially mocked within the test file', () => {
React.lazy.mockRestore();
expect(jest.isMockFunction(React.lazy)).toBe(false);
});
});
Run Code Online (Sandbox Code Playgroud)
页面/Home/__tests__/Home.test.js
import React from 'react';
import Home from '../index.js';
describe('Home', () => {
const wrapper = shallow(<Home />);
it('renders without errors', () => {
const homeComponent = wrapper.find('.app');
expect(homeComponent).toHaveLength(1);
});
it('should partially mock React module', async () => {
expect(jest.isMockFunction(React.lazy)).toBe(true);
});
});
Run Code Online (Sandbox Code Playgroud)
工作示例:https ://github.com/mattcarlotta/named-react-lazy-mocked
安装:
git clone git@github.com:mattcarlotta/named-react-lazy-mocked.git
cd named-react-lazy-mocked
yarn install
yarn test
utils/__mocks__/react.js
jest.mock('react', () => ({
...require.requireActual('react'),
lazy: jest.fn(),
}));
module.exports = require.requireMock('react');
Run Code Online (Sandbox Code Playgroud)
utils/setup/setupTest.js(可选地,您可以将模拟react
文件添加为global
玩笑函数,这样您就不必import * as React from 'react'
为每个测试编写):
import { JSDOM } from 'jsdom';
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
// import React from '../__mocks__/react';
configure({ adapter: new Adapter() });
// global.React = React;
Run Code Online (Sandbox Code Playgroud)
根/__tests__/root.test.js
import * as React from 'react';
import App from '../index.js';
const React2 = require('react');
describe('App', () => {
const wrapper = mount(<App />);
it('renders without errors', () => {
const homeComponent = wrapper.find('.app');
expect(homeComponent).toHaveLength(1);
});
it('should partially mock React module', async () => {
expect(jest.isMockFunction(await require('react').lazy)).toBe(true); // eslint-disable-line global-require
expect(jest.isMockFunction(React)).toBe(false);
expect(jest.isMockFunction(React.lazy)).toBe(true);
expect(jest.isMockFunction(React2)).toBe(false);
expect(jest.isMockFunction(React2.lazy)).toBe(true);
});
});
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3193 次 |
最近记录: |