jay*_*ara 5 javascript testing reactjs jestjs react-18
我刚刚开始学习 Daniel Irvine 的《Mastering React Test-Driven Development》,我认为将示例转换为 React 18 应该不会太难。但是我在转换书中的第一个测试时遇到了麻烦使用笑话。
\n这本书没有使用create-react-app任何东西,而是从头开始构建 React 应用程序,所以我很难找到如何转换代码的相关示例。
当按照书中的 React 17 风格编写时,测试通过了。但如果我替换ReactDOM.render()为createRoot(),测试就会失败。
我的应用程序目录如下所示:
\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 package.json\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 package-lock.json\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 src\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 Appointment.js\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 test\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 Appointment.test.js\nRun Code Online (Sandbox Code Playgroud)\n文件内容是:
\npackage.json:
{\n "name": "appointments",\n "version": "1.0.0",\n "description": "Appointments project from Mastering React Test-Driven Development.",\n "main": "index.js",\n "scripts": {\n "test": "jest"\n },\n "repository": {\n "type": "git",\n "url": "example.com"\n },\n "author": "",\n "license": "ISC",\n "devDependencies": {\n "@babel/plugin-transform-runtime": "^7.18.6",\n "@babel/preset-env": "^7.18.6",\n "@babel/preset-react": "^7.18.6",\n "jest": "^28.1.2",\n "jest-environment-jsdom": "^28.1.3"\n },\n "dependencies": {\n "@babel/runtime": "^7.18.6",\n "react": "^18.2.0",\n "react-dom": "^18.2.0"\n },\n "jest": {\n "testEnvironment": "jsdom"\n }\n}\nRun Code Online (Sandbox Code Playgroud)\nsrc/Appointment.js:
import React from \'react\';\n\nexport const Appointment = () => <div>Ashley</div>;\nRun Code Online (Sandbox Code Playgroud)\ntest/Appointment.test.js:
import React from \'react\';\nimport ReactDOM from \'react-dom\';\n// import {createRoot} from \'react-dom/client\';\n\nimport {Appointment} from \'../src/Appointment\';\n\ndescribe(\'Appointment\', () => {\n it("renders the customer\'s first name.", () => {\n const customer = {firstName: \'Ashley\'};\n const component = <Appointment customer={customer} />;\n const container = document.createElement(\'div\');\n document.body.appendChild(container);\n\n ReactDOM.render(component, container);\n\n // const root = createRoot(container);\n // root.render(component);\n\n expect(document.body.textContent).toMatch(\'Ashley\');\n });\n});\nRun Code Online (Sandbox Code Playgroud)\n使用ReactDOM.render(),测试通过,但出现以下错误:
console.error\n Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it\'s running React 17. Learn more: https://reactjs.org/link/switch-to-createroot\n\n 11 | document.body.appendChild(container);\n 12 |\n > 13 | ReactDOM.render(component, container);\n | ^\n 14 |\n 15 | expect(document.body.textContent).toMatch(\'Ashley\');\n 16 | });\n\n at printWarning (node_modules/react-dom/cjs/react-dom.development.js:86:30)\n at error (node_modules/react-dom/cjs/react-dom.development.js:60:7)\n at Object.render (node_modules/react-dom/cjs/react-dom.development.js:29670:5)\n at Object.render (test/Appointment.test.js:13:14)\nRun Code Online (Sandbox Code Playgroud)\n我查找了如何转换ReactDOM.render()为createRoot(),并将测试更改为:
import React from \'react\';\n// import ReactDOM from \'react-dom\';\nimport {createRoot} from \'react-dom/client\';\n\nimport {Appointment} from \'../src/Appointment\';\n\ndescribe(\'Appointment\', () => {\n it("renders the customer\'s first name.", () => {\n const customer = {firstName: \'Ashley\'};\n const component = <Appointment customer={customer} />;\n const container = document.createElement(\'div\');\n document.body.appendChild(container);\n\n // ReactDOM.render(component, container);\n\n const root = createRoot(container);\n root.render(component);\n\n expect(document.body.textContent).toMatch(\'Ashley\');\n });\n});\nRun Code Online (Sandbox Code Playgroud)\n并且测试失败如下:
\n\n> appointments@1.0.0 test\n> jest\n\n FAIL test/Appointment.test.js\n Appointment\n \xe2\x9c\x95 renders the customer\'s first name. (9 ms)\n\n \xe2\x97\x8f Appointment \xe2\x80\xba renders the customer\'s first name.\n\n expect(received).toMatch(expected)\n\n Expected substring: "Ashley"\n Received string: ""\n\n 17 | root.render(component);\n 18 |\n > 19 | expect(document.body.textContent).toMatch(\'Ashley\');\n | ^\n 20 | });\n 21 | });\n 22 |\n\n at Object.toMatch (test/Appointment.test.js:19:39)\n at TestScheduler.scheduleTests (node_modules/@jest/core/build/TestScheduler.js:317:13)\n at runJest (node_modules/@jest/core/build/runJest.js:407:19)\n at _run10000 (node_modules/@jest/core/build/cli/index.js:339:7)\n at runCLI (node_modules/@jest/core/build/cli/index.js:190:3)\n\nTest Suites: 1 failed, 1 total\nTests: 1 failed, 1 total\nSnapshots: 0 total\nTime: 0.979 s, estimated 1 s\nRan all test suites.\nRun Code Online (Sandbox Code Playgroud)\n我怎样才能通过使用这个测试createRoot()?
经过更多研究后,我发现act()可以在 React 18 中使用它来强制在检查测试断言之前进行渲染。这允许测试立即运行,而无需在测试失败时等待 Jest 的 did() 超时。
globals.IS_REACT_ACT_ENVIRONMENTtrue必须在 Jest 配置中设置为。我在这里更新了package.json:
package.json:
...
"jest": {
"testEnvironment": "jsdom",
"globals": {
"IS_REACT_ACT_ENVIRONMENT": true
}
}
...
Run Code Online (Sandbox Code Playgroud)
然后可以更新测试以使用act()以下版本react-dom/test-utils:
import React from 'react';
import {createRoot} from 'react-dom/client';
import {act} from 'react-dom/test-utils';
import {Appointment} from '../src/Appointment';
describe('Appointment', () => {
it("renders the customer's first name.", () => {
const customer = {firstName: 'Ashley'};
const component = <Appointment customer={customer} />;
const container = document.createElement('div');
document.body.appendChild(container);
const root = createRoot(container);
act(() => root.render(component));
expect(document.body.textContent).toMatch('Ashley');
});
});
Run Code Online (Sandbox Code Playgroud)
资源:
act()实用程序文档:https://reactjs.org/docs/test-utils.html#actact()在 React 18 中设置: https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html#configuring-your-testing-environment| 归档时间: |
|
| 查看次数: |
3855 次 |
| 最近记录: |