【问题标题】:enzyme react component test throws window.requestAnimationFrame TypeError酶反应组件测试抛出 window.requestAnimationFrame TypeError
【发布时间】:2022-02-11 18:24:17
【问题描述】:

我正在尝试测试我们的 SPFx React 组件。
我们正在使用以下技术:

  • spfx 1.13.1
  • 反应 16.13.1
  • 开玩笑 27.4.7
  • 酶 3.11.0
  • 打字稿 4.2.4
  • fabric-ui: 1.13.1

我在使用 enzym.mount 运行简单测试时遇到以下错误。

TypeError: window.requestAnimationFrame is not a function

  at Stylesheet.Object.<anonymous>.Stylesheet._getStyleElement (node_modules/@uifabric/merge-styles/src/Stylesheet.ts:295:16)
  at Stylesheet.Object.<anonymous>.Stylesheet.insertRule (node_modules/@uifabric/merge-styles/src/Stylesheet.ts:227:65)
  at applyRegistration (node_modules/@uifabric/merge-styles/src/styleToClassName.ts:284:20)
  at Object.styleToClassName (node_modules/@uifabric/merge-styles/src/styleToClassName.ts:294:5)
  at mergeCss (node_modules/@uifabric/merge-styles/src/mergeStyles.ts:30:18)
  at Object.mergeStyles (node_modules/@uifabric/merge-styles/src/mergeStyles.ts:13:10)
  at Object.<anonymous> (node_modules/@uifabric/utilities/src/scroll.ts:9:33)

根据其他各种答案(herehere),我尝试使用以下代码

global.requestAnimationFrame = function (callback) {
    return setTimeout(callback, 0);
};

将它放在我的测试代码的顶部、describe 和单独的 test-init 文件中。

我也尝试使用ras/polyfill,但错误没有任何变化。

对推动我找到可行的解决方案有什么帮助吗?

测试文件。

/// <reference types="jest" />

import * as React from 'react';
import { configure, mount, ReactWrapper, shallow } from 'enzyme';
import * as Adapter from 'enzyme-adapter-react-16';
import "jsdom-global/register";

import MyComponent, { IMyComponentProps, IMyComponentState } from './my-component';

// import { polyfill } from 'raf';
// polyfill();

// global.requestAnimationFrame = function (callback) {
//     return setTimeout(callback, 0);
// };

configure({ adapter: new Adapter() });

describe('<MyComponent/>', () => {
    let renderedElement: ReactWrapper<IMyComponentProps, IMyComponentState>;

    beforeEach(() => {
        renderedElement = mount(<MyComponent/>);
    });

    afterEach(() => {
        renderedElement.unmount();
    });

    it('load my component', () => {
        expect(renderedElement).toBeTruthy();
    });

});

组件控件

<TextField name='abc' label="" defaultValue={state.abc} onChange={_handleChange} />
<Dropdown label='xyz' placeholder='Select xyz' options={options} defaultSelectedKey={state.xyz} onChange={(e, i) => _handleChangeDropdown(e, i, 'xyz')} />

package.json 文件

  ...
  "devDependencies": {
    "@microsoft/microsoft-graph-types": "^2.11.0",
    "@microsoft/rush-stack-compiler-4.2": "0.1.1",
    "@microsoft/sp-build-web": "1.13.1",
    "@microsoft/sp-module-interfaces": "1.13.1",
    "@types/enzyme": "^3.10.11",
    "@types/jest": "^27.4.0",
    "@types/node": "^17.0.10",
    "@types/react": "17.0.38",
    "@types/react-dom": "17.0.11",
    "@types/react-router-dom": "^5.3.2",
    "@types/webpack-env": "1.16.3",
    "@typescript-eslint/eslint-plugin": "^5.9.1",
    "@typescript-eslint/parser": "^5.9.1",
    "ajv": "~8.8.2",
    "enzyme": "^3.11.0",
    "enzyme-adapter-react-16": "^1.15.6",
    "eslint": "^8.6.0",
    "eslint-config-react-app": "^7.0.0",
    "eslint-plugin-react": "^7.28.0",
    "gulp": "~4.0.2",
    "gulp-eslint-new": "^1.1.1",
    "identity-obj-proxy": "^3.0.0",
    "jest": "^27.4.7",
    "jest-junit": "^13.0.0",
    "jsdom": "^19.0.0",
    "jsdom-global": "^3.0.2",
    "raf": "^3.4.1",
    "react-test-renderer": "^17.0.2",
    "spfx-fast-serve-helpers": "~1.13.0",
    "ts-jest": "^27.1.3",
    "typescript": "4.2.4"
},
"jest": {
    "moduleFileExtensions": [
        "ts",
        "tsx",
        "js"
    ],
    "moduleDirectories": [
        "node_modules"
    ],
    "moduleNameMapper": {
        "\\.(css|less|scss|sass)$": "identity-obj-proxy",
        "office-ui-fabric-react/lib/(.*)$": "office-ui-fabric-react/lib-commonjs/$1",
        "^@mywebpart/(.*)": "<rootDir>/src/webparts/mywebpart/$1",
        "^@shared/(.*)": "<rootDir>/src/shared/$1"
    },
    "transform": {
        "^.+\\.(ts|tsx)$": "ts-jest"
    },
    "testMatch": [
        "**/src/**/*.tests.+(ts|tsx)"
    ],
    "setupFiles": [
        "<rootDir>/src/webparts/mywebpart/tests/tests-setup.ts"
    ],
    "collectCoverage": true,
    "coverageReporters": [
        "json",
        "lcov",
        "text",
        "cobertura"
    ],
    "coverageDirectory": "<rootDir>/test-results",
    "reporters": [
        "default",
        "jest-junit"
    ],
    "coverageThreshold": {
        "global": {
            "branches": 60,
            "functions": 60,
            "lines": 60,
            "statements": 60
        }
    }
},
"jest-junit": {
    "output": "./test-results/summary-jest-junit.xml"
}

tsconfig.json 文件

{
  "extends": "./node_modules/@microsoft/rush-stack-compiler-4.2/includes/tsconfig-web.json",
  "compilerOptions": {
    "target": "es5",
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "jsx": "react",
    "declaration": true,
    "sourceMap": true,
    "experimentalDecorators": true,
    "skipLibCheck": true,
    "outDir": "lib",
    "inlineSources": false,
    "strictNullChecks": false,
    "noUnusedLocals": false,
    "allowSyntheticDefaultImports": true,
    "resolveJsonModule": true,
    "typeRoots": [
      "./node_modules/@types",
      "./node_modules/@microsoft"
    ],
    "types": [
      "webpack-env",
      "jest",
      "node"
    ],
    "lib": [
      "es6",
      "dom",
      "es2015.collection",
      "es2015.promise"
    ],
    "baseUrl": "src",
    "paths": {
      "@mywebpart/*": [
        "webparts/mywebpart/*"
      ],
      "@shared/*": [
        "shared/*"
      ]
    }
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx"
  ]
}

【问题讨论】:

    标签: jestjs enzyme spfx


    【解决方案1】:

    我能够解决这个问题,但我不能 100% 确定我可以按照流程进行。

    我创建了一个用 jest 配置的测试设置文件。

        "setupFiles": [
            "<rootDir>/src/webparts/fuhrpark/tests/tests-setup.ts"
        ],
    

    文件内容。

    /// <reference types="jest" />
    
    import "jsdom-global/register";
    // Polyfill requestAnimiationFrame
    import "raf/polyfill";
    
    import { configure } from 'enzyme';
    import * as Adapter from 'enzyme-adapter-react-16';
    import { setIconOptions } from "office-ui-fabric-react/lib/Styling";
    
    // Suppress icon warnings.
    setIconOptions({
        disableWarnings: true
    });
    
    // Fail on warnings.
    const consoleError = console.error;
    console.error = console.warn = (message) => {
        // Ignore error boundary warnings so that tests which throw exceptions can be validated.
        if (message.indexOf('error boundary') >= 0) {
            return;
        }
    
        consoleError(message);
        throw new Error("Caught: " + message);
    };
    
    // configure enzyme adapter
    configure({ adapter: new Adapter() });
    

    【讨论】:

      猜你喜欢
      • 2017-08-16
      • 2018-01-17
      • 2019-01-30
      • 2017-05-20
      • 2017-09-24
      • 1970-01-01
      • 2018-03-23
      • 2016-04-28
      • 1970-01-01
      相关资源
      最近更新 更多