Enzyme 需要配置一个适配器
Enzyme expects an adapter to be configured
我通过 create-react-app 创建了一个新的 React 应用程序,我想对我在应用程序中创建的名为 "MessageBox" 的组件编写单元测试。这是我写的单元测试:
import MessageBox from "../MessageBox";
import { shallow } from 'enzyme';
import React from 'react';
test('message box', () => {
const app = {setState: jest.fn()};
const wrapper = shallow(<MessageBox app={app}/>);
wrapper.find('button').at(0).simulate('click');
expect(app.setState).toHaveBeenLastCalledWith({modalIsOpen: false});
});
我还在 'src' 文件夹下添加了一个名为 'setupTests.js' 的文件,内容为:
import * as enzyme from 'enzyme';
import * as Adapter from 'enzyme-adapter-react-16';
enzyme.configure({ adapter: new Adapter() });
我运行它通过:
npm test
我得到了错误:
Enzyme Internal Error: Enzyme expects an adapter to be configured, but
found none. To configure an adapter, you should call Enzyme.configure({ > adapter: new Adapter() })
你知道什么可以解决这个问题吗?
将 import React from 'react';
添加到文件的顶部。
您正在使用 JSX 语法 <MessageBox app={app}/>
,其中 transpiles 变为 React.createComponent(...)
。为了使其工作 React
必须在文件范围内定义变量。
必须将文件 'setupTests' 导入到测试文件中:
import MessageBox from "../MessageBox";
import { shallow } from 'enzyme';
import React from 'react';
import "../setupTests"
test('message box', ()=> {
...
})
将其添加到您的测试用例文件中。
import React from 'react';
import Adapter from 'enzyme-adapter-react-16';
import { shallow, configure } from 'enzyme';
configure({adapter: new Adapter()});
test('message box', ()=> {
...
})
您需要像这样使用导入:
import Adapter from 'enzyme-adapter-react-16';
这样:(import * as Adapter from ...) returns 一条消息 "TypeError: Adapter is not a constructor."
此外,如果您不想将 setupTests.js 文件导入到每个测试文件中,您可以将其放在 package.json 文件夹中:
"jest": {
"setupTestFrameworkScriptFile": "./test/setupTests.js" }
更新:
Note: setupTestFrameworkScriptFile is deprecated in favor of setupFilesAfterEnv.
试试这样的东西;
import React from 'react';
import App from './containers/App';
import enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
enzyme.configure({ adapter: new Adapter() });
describe('App Screen', () => {
let mountedAppScreen;
let props;
const appScreen = () => {
if (!mountedAppScreen) {
mountedAppScreen = enzyme.mount(
<App {...props} />
);
}
return mountedAppScreen;
}
it("it always renders div", () => {
const divs = appScreen().find("div");
expect(divs.length).toBeGreaterThanOrEqual(1);
});
});
使用最新版本的库,我遇到了这个问题的每个答案中报告的相同错误。错误:类型错误:适配器不是构造函数。
为了使用 Enzyme 正确测试你的 ReactJS 组件,我已经将所有必要的步骤组合在一起(我使用了 Jest,但它也可能适用于 Mocha,在这种情况下,只需切换主要测试包):
1) 图书馆 (package.json):
"dependencies": {
"jest": "^24.6.0",
(...)
}
"devDependencies": {
"chai": "^4.2.0",
"enzyme": "^3.7.0",
"enzyme-adapter-react-16": "^1.7.0",
(...)
}
2) 测试设置:您可以在每个测试中设置酶。但正如 type_master_flash 明智地建议的那样,您可以添加一个脚本来执行此操作。为此,请在您的 package.json 文件中与会话 脚本、依赖项等 的同一级别创建一个新设置:
Jest 版本 23.x(或更早版本):
"devDependencies": {
(...)
},
"jest": {
"setupTestFrameworkScriptFile": "./tests.setup.js"
},
Jest 24.0 版本之后: 根据 Jest Documentation,“setupTestFrameworkScriptFile 已弃用,取而代之的是 setupFilesAfterEnv”。
"devDependencies": {
(...)
},
"jest": {
"setupFilesAfterEnv": ["./tests.setup.js"]
},
这个文件可以放在任何你喜欢的地方,你可以随意命名。请记住设置正确的文件位置。在当前示例中,我将文件存储在项目的根目录中。
3) tests.setup.js:正如我在 中发现的那样,这里的问题是我们不能“导入 '' 具有默认导出的模块"。配置文件的正确方法是:
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
Enzyme.configure({ adapter: new Adapter() });
仅此而已,您就可以测试您的组件了。
干杯,希望这有帮助。
与 一样,如果您使用的是 Create React App,它将从 src/setupTests.js
中获取配置。
添加:
import { configure } from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
configure({ adapter: new Adapter() })
很多答案都说将 setupTests.js
导入到您的测试文件中。要么
在每个测试文件中配置酶适配器。这确实解决了眼前的问题。
但从长远来看,如果您将 jest.config.js
文件添加到项目根目录。您可以将其配置为 运行 启动时的安装文件。
jest.config.js
module.exports = {
setupTestFrameworkScriptFile: "<rootDir>/src/setupTests.ts"
}
这会告诉 Jest 每次启动时 运行 setupTest.ts。
通过这种方式,如果您需要添加 polyfill 或添加全局模拟(如 localstorage),您可以将其添加到您的 setupTests
文件中并在任何地方进行配置。
Enzyme 文档不涉及与 Jest 的集成,因此将两者融合在一起会造成混淆。
对于以后阅读本文的每个人,documentation 在新版本中弃用了 setupTestFrameworkScriptFile
,取而代之的是 setupFilesAfterEnv
。我们可以这样添加我们的文件:
"setupFiles": [
"<rootDir>/src/setupTests.js"
]
对我来说,在 create-react-app
中使用 React 时,我必须确保文件名是正确的。该文件必须是 src/setupTests.js
,在 Tests
末尾有一个 s
。
里面 setupTests.js
是这样的:
import { configure } from "enzyme";
import Adapter from "enzyme-adapter-react-16";
configure({ adapter: new Adapter() });
当 运行 npm run test
时,它会自动找到 setupTests.js
文件。无需导入到每个测试文件中。
我遇到了同样的错误,出于某种原因,React 没有自动获取 setupTests.js
文件。
我在根目录创建了一个名为 jest.config.js
的新文件并添加了
{ "jest": { "setupTestFrameworkScriptFile": "<rootDir>/path/to/your/file.js", } }
在此之后,错误消失了。
注意: 后来,我 删除了 jest.config.js
文件,但它现在仍然有效。
但不确定究竟是什么导致了问题!
文件配置必须在setupFilesAfterEnv
属性 of jest.config.js
{
...
setupFilesAfterEnv: ["<rootDir>/jest.transform.js"],
...
}
如果有人在 GatsbyJs 中使用 Jest 测试 React 组件后尝试修复此问题 (https://www.gatsbyjs.org/docs/testing-react-components/)
在您制作的 setup-test-env.js
中,将其编辑为如下所示:
import "@testing-library/jest-dom/extend-expect"
import { configure } from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
configure({ adapter: new Adapter() })
在项目的根目录中创建一个名为 setupTests.js 的文件。 jest 会在 运行 任何测试服之前自动查找此文件。将以下内容添加到文件中。
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
Enzyme.configure({adapter:new Adapter()})
注意:文件名应该与 same.no 完全相同,将此 setupTests.js 文件导入您的测试 files.it 将自动运行
对于那些在 React CRA 应用程序中使用 VS Code 和 Jest Runner 扩展的用户,不要忘记 configure Jest Runner 通过将 jest 命令设置为以下命令来使用 CRA 的内置脚本运行器:
npm 测试 -- --watchAll=false
如果您忘记这样做,您将在主题中遇到错误。由于您使用的是 CRA,因此您将无法在 package.json 或 jest.config.js 中配置 setupFilesAfterEnv。尝试这样做会导致此错误:
Create React App 当前不支持 package.json Jest 配置中的这些选项
npm i enzyme-adapter-react-16 enzyme-to-json --save-dev
添加到package.json
enter image description here
"jest": {
"collectCoverageFrom": [ "src/**/*.js", "!src/index.js" ]
};
- 将两个文件添加到 src 文件夹 ->
setupTests.js
tempPolyfills.js
setupTests.js
:
import requestAnimationFrame from './tempPolyfills';
import { configure } from "enzyme";
import Adapter from 'enzyme-adapter-react-16';
configure({adapter: new Adapter(), disableLifecycleMethods:true});
tempPolyfills.js
:
const requestAnimationFrame = global.requestAnimationFrame = callback => {
setTimeout(callback,0);
};
export default requestAnimationFrame;
- 如果 shallow -> expect() 在测试用例中失败,请使用 toJson() :
示例:
import { shallow } from "enzyme";
import App from "./App";
import toJson from 'enzyme-to-json';
describe('App', () => {
const app = shallow(<App />);
it('renders correctly', () => {
expect(toJson(app)).toMatchSnapshot();
});
});
如果你认为你已经正确地设置了所有东西(例如,安装了支持 React 17 的 @wojtekmaj/enzyme-adapter-react-17),还有一个需要检查 Typescript 的陷阱:
你有
"esModuleInterop": true,
以及适配器的匹配导入格式?
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
import Enzyme from 'enzyme';
我通过 create-react-app 创建了一个新的 React 应用程序,我想对我在应用程序中创建的名为 "MessageBox" 的组件编写单元测试。这是我写的单元测试:
import MessageBox from "../MessageBox";
import { shallow } from 'enzyme';
import React from 'react';
test('message box', () => {
const app = {setState: jest.fn()};
const wrapper = shallow(<MessageBox app={app}/>);
wrapper.find('button').at(0).simulate('click');
expect(app.setState).toHaveBeenLastCalledWith({modalIsOpen: false});
});
我还在 'src' 文件夹下添加了一个名为 'setupTests.js' 的文件,内容为:
import * as enzyme from 'enzyme';
import * as Adapter from 'enzyme-adapter-react-16';
enzyme.configure({ adapter: new Adapter() });
我运行它通过:
npm test
我得到了错误:
Enzyme Internal Error: Enzyme expects an adapter to be configured, but found none. To configure an adapter, you should call
Enzyme.configure({ > adapter: new Adapter() })
你知道什么可以解决这个问题吗?
将 import React from 'react';
添加到文件的顶部。
您正在使用 JSX 语法 <MessageBox app={app}/>
,其中 transpiles 变为 React.createComponent(...)
。为了使其工作 React
必须在文件范围内定义变量。
必须将文件 'setupTests' 导入到测试文件中:
import MessageBox from "../MessageBox";
import { shallow } from 'enzyme';
import React from 'react';
import "../setupTests"
test('message box', ()=> {
...
})
将其添加到您的测试用例文件中。
import React from 'react';
import Adapter from 'enzyme-adapter-react-16';
import { shallow, configure } from 'enzyme';
configure({adapter: new Adapter()});
test('message box', ()=> {
...
})
您需要像这样使用导入:
import Adapter from 'enzyme-adapter-react-16';
这样:(import * as Adapter from ...) returns 一条消息 "TypeError: Adapter is not a constructor."
此外,如果您不想将 setupTests.js 文件导入到每个测试文件中,您可以将其放在 package.json 文件夹中:
"jest": {
"setupTestFrameworkScriptFile": "./test/setupTests.js" }
更新:
Note: setupTestFrameworkScriptFile is deprecated in favor of setupFilesAfterEnv.
试试这样的东西;
import React from 'react';
import App from './containers/App';
import enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
enzyme.configure({ adapter: new Adapter() });
describe('App Screen', () => {
let mountedAppScreen;
let props;
const appScreen = () => {
if (!mountedAppScreen) {
mountedAppScreen = enzyme.mount(
<App {...props} />
);
}
return mountedAppScreen;
}
it("it always renders div", () => {
const divs = appScreen().find("div");
expect(divs.length).toBeGreaterThanOrEqual(1);
});
});
使用最新版本的库,我遇到了这个问题的每个答案中报告的相同错误。错误:类型错误:适配器不是构造函数。
为了使用 Enzyme 正确测试你的 ReactJS 组件,我已经将所有必要的步骤组合在一起(我使用了 Jest,但它也可能适用于 Mocha,在这种情况下,只需切换主要测试包):
1) 图书馆 (package.json):
"dependencies": {
"jest": "^24.6.0",
(...)
}
"devDependencies": {
"chai": "^4.2.0",
"enzyme": "^3.7.0",
"enzyme-adapter-react-16": "^1.7.0",
(...)
}
2) 测试设置:您可以在每个测试中设置酶。但正如 type_master_flash 明智地建议的那样,您可以添加一个脚本来执行此操作。为此,请在您的 package.json 文件中与会话 脚本、依赖项等 的同一级别创建一个新设置:
Jest 版本 23.x(或更早版本):
"devDependencies": {
(...)
},
"jest": {
"setupTestFrameworkScriptFile": "./tests.setup.js"
},
Jest 24.0 版本之后: 根据 Jest Documentation,“setupTestFrameworkScriptFile 已弃用,取而代之的是 setupFilesAfterEnv”。
"devDependencies": {
(...)
},
"jest": {
"setupFilesAfterEnv": ["./tests.setup.js"]
},
这个文件可以放在任何你喜欢的地方,你可以随意命名。请记住设置正确的文件位置。在当前示例中,我将文件存储在项目的根目录中。
3) tests.setup.js:正如我在
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
Enzyme.configure({ adapter: new Adapter() });
仅此而已,您就可以测试您的组件了。
干杯,希望这有帮助。
与 src/setupTests.js
中获取配置。
添加:
import { configure } from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
configure({ adapter: new Adapter() })
很多答案都说将 setupTests.js
导入到您的测试文件中。要么
在每个测试文件中配置酶适配器。这确实解决了眼前的问题。
但从长远来看,如果您将 jest.config.js
文件添加到项目根目录。您可以将其配置为 运行 启动时的安装文件。
jest.config.js
module.exports = {
setupTestFrameworkScriptFile: "<rootDir>/src/setupTests.ts"
}
这会告诉 Jest 每次启动时 运行 setupTest.ts。
通过这种方式,如果您需要添加 polyfill 或添加全局模拟(如 localstorage),您可以将其添加到您的 setupTests
文件中并在任何地方进行配置。
Enzyme 文档不涉及与 Jest 的集成,因此将两者融合在一起会造成混淆。
对于以后阅读本文的每个人,documentation 在新版本中弃用了 setupTestFrameworkScriptFile
,取而代之的是 setupFilesAfterEnv
。我们可以这样添加我们的文件:
"setupFiles": [
"<rootDir>/src/setupTests.js"
]
对我来说,在 create-react-app
中使用 React 时,我必须确保文件名是正确的。该文件必须是 src/setupTests.js
,在 Tests
末尾有一个 s
。
里面 setupTests.js
是这样的:
import { configure } from "enzyme";
import Adapter from "enzyme-adapter-react-16";
configure({ adapter: new Adapter() });
当 运行 npm run test
时,它会自动找到 setupTests.js
文件。无需导入到每个测试文件中。
我遇到了同样的错误,出于某种原因,React 没有自动获取 setupTests.js
文件。
我在根目录创建了一个名为 jest.config.js
的新文件并添加了
{ "jest": { "setupTestFrameworkScriptFile": "<rootDir>/path/to/your/file.js", } }
在此之后,错误消失了。
注意: 后来,我 删除了 jest.config.js
文件,但它现在仍然有效。
但不确定究竟是什么导致了问题!
文件配置必须在setupFilesAfterEnv
属性 of jest.config.js
{
...
setupFilesAfterEnv: ["<rootDir>/jest.transform.js"],
...
}
如果有人在 GatsbyJs 中使用 Jest 测试 React 组件后尝试修复此问题 (https://www.gatsbyjs.org/docs/testing-react-components/)
在您制作的 setup-test-env.js
中,将其编辑为如下所示:
import "@testing-library/jest-dom/extend-expect"
import { configure } from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
configure({ adapter: new Adapter() })
在项目的根目录中创建一个名为 setupTests.js 的文件。 jest 会在 运行 任何测试服之前自动查找此文件。将以下内容添加到文件中。
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
Enzyme.configure({adapter:new Adapter()})
注意:文件名应该与 same.no 完全相同,将此 setupTests.js 文件导入您的测试 files.it 将自动运行
对于那些在 React CRA 应用程序中使用 VS Code 和 Jest Runner 扩展的用户,不要忘记 configure Jest Runner 通过将 jest 命令设置为以下命令来使用 CRA 的内置脚本运行器:
npm 测试 -- --watchAll=false
如果您忘记这样做,您将在主题中遇到错误。由于您使用的是 CRA,因此您将无法在 package.json 或 jest.config.js 中配置 setupFilesAfterEnv。尝试这样做会导致此错误:
Create React App 当前不支持 package.json Jest 配置中的这些选项
npm i enzyme-adapter-react-16 enzyme-to-json --save-dev
添加到
package.json
enter image description here
"jest": {
"collectCoverageFrom": [ "src/**/*.js", "!src/index.js" ]
};
- 将两个文件添加到 src 文件夹 ->
setupTests.js
tempPolyfills.js
setupTests.js
:
import requestAnimationFrame from './tempPolyfills';
import { configure } from "enzyme";
import Adapter from 'enzyme-adapter-react-16';
configure({adapter: new Adapter(), disableLifecycleMethods:true});
tempPolyfills.js
:
const requestAnimationFrame = global.requestAnimationFrame = callback => { setTimeout(callback,0); }; export default requestAnimationFrame;
- 如果 shallow -> expect() 在测试用例中失败,请使用 toJson() : 示例:
import { shallow } from "enzyme";
import App from "./App";
import toJson from 'enzyme-to-json';
describe('App', () => {
const app = shallow(<App />);
it('renders correctly', () => {
expect(toJson(app)).toMatchSnapshot();
});
});
如果你认为你已经正确地设置了所有东西(例如,安装了支持 React 17 的 @wojtekmaj/enzyme-adapter-react-17),还有一个需要检查 Typescript 的陷阱:
你有
"esModuleInterop": true,
以及适配器的匹配导入格式?
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
import Enzyme from 'enzyme';