【问题标题】:Unit testing ES7 React components with Jest使用 Jest 对 ES7 React 组件进行单元测试
【发布时间】:2017-12-01 07:50:29
【问题描述】:

如何让 Jest 与 ES7 初始化程序很好地配合?我在这里和其他来源进行了广泛搜索,但没有找到任何结论。

.babelrc.js

{
    "env": {
        "development": {
            "presets": [["es2015", { "modules": false }], "react", "react-hmre"],
            "plugins": [
                "transform-class-properties",
                "react-hot-loader/babel"
            ]
        },
        "test": {
            "presets": ["env", "react"],
            "plugins": ["transform-class-properties"]
        },
        "production": {
            "presets": [["es2015", { "modules": false }], "react"],
            "plugins": ["transform-class-properties"]
        }
    }
}

package.json

    {
    "name": "demo",
    "version": "1.0.0",
    "main": "index.js",
    "license": "MIT",
    "private": true,
    "dependencies": {
        "react": "^15.5.4",
        "react-dom": "^15.5.4",
    },
    "devDependencies": {
        "babel-cli": "^6.24.1",
        "babel-core": "^6.24.1",
        "babel-jest": "^20.0.3",
        "babel-plugin-transform-class-properties": "^6.24.1",
        "babel-polyfill": "^6.23.0",
        "babel-preset-env": "^1.5.2",
        "babel-preset-es2015": "^6.24.1",
        "babel-preset-react": "^6.24.1",
        "babel-preset-react-hmre": "^1.1.1",
        "enzyme": "^2.8.2",
        "react-hot-loader": "next",
        "babel-plugin-import": "^1.2.1",
        "enzyme": "^2.9.1",
        "enzyme-to-json": "^1.5.1"
    },
    "scripts": {
        "test": "export NODE_ENV=test && ./node_modules/.bin/jest --no-cache"
    },
    "engines": {
        "node": ">= 7.8.0"
    },
    "jest": {
        "verbose": true,
        "collectCoverage": true,
        "coverageDirectory": "__coverage__",
        "mapCoverage": true,
        "setupFiles": [
            "./tests/setup.js"
        ],
        "testPathIgnorePatterns": [
            "/node_modules/"
        ],
        "transform": {
            "\\.js$": "../node_modules/babel-jest"
        },
        "testRegex": ".*\\.test\\.js$",
        "snapshotSerializers": [
            "enzyme-to-json/serializer"
        ]
    }
}

Demo.jsx

import React from 'react';
import PropTypes from 'prop-types';

export class Demo extends React.Component {

    static props = { name: PropTypes.string.isRequired };

    constructor(props) {
        super(props);
    }

    render() {
        return (
            <div className='demo'>{this.props.name}</div>
        );
    }

}

Demo.test.js

import React from 'react';
import { Demo } from '..';
import { render } from 'enzyme';


describe('Demo', () => {
    it('renders correctly', () => {
        const wrapper = render(<Demo name="foo" />);
        expect(wrapper).toMatchSnapshot();
    });
});

运行yarn testexport NODE_ENV=test &amp;&amp; ../node_modules/.bin/jest --no-cache 后,Jest 会抱怨它看到了一个意外字符

 8 |     props = {
   |           ^
 9 |         name: PropTypes.string.isRequired

据我了解,运行测试时设置的环境变量应该会自动将初始化程序转换为 Jest 可以使用的东西,但这似乎没有发生。

我也在使用 webpack 2.x,但是让它工作的配置开销似乎令人生畏。还有其他方法吗?

更新 1

我修改了我的 Jest 设置如下:

 "transform": {
      "\\.js$": "./node_modules/babel-plugin-transform-class-properties"
 }

这立即失败了:

TypeError: Jest: 转换必须导出 process 函数。

完全删除 transform 会产生一个稍微不同的问题:

TypeError: 无法读取 null 的属性“props”

我还将constructor 添加到Demo 组件中。

【问题讨论】:

  • 这是一个愚蠢的问题,但是您确定新功能的语法吗?我在野外看到过类似的 TC39 插件,但使用 props: {name: ...} 而不是 props = {name: ...}
  • 另外,组件是否正确渲染,还是仅在 Jest 测试期间失败?
  • 适用于 webpack 2
  • 这个问题有什么进展吗?我也想使用类属性,但没有 Jest 支持成为障碍。 create-react-app 很好地支持带有 Babel 类属性的 Jest 测试:github.com/facebookincubator/create-react-app/blob/master/…

标签: javascript unit-testing reactjs babeljs jestjs


【解决方案1】:

Jest 使用 babel 转译 JS 代码。您需要在 .babelrc 文件中添加对 ES7 功能的支持。

步骤如下:

  1. npm install --save-dev babel-preset-stage-0 babel-jest
  2. 在您的 package.json 中,添加 babel-jest 用于转换所有 js 文件。
  3. 在您的 .babelrc 文件中,添加 "stage-0" 预设。

这是我的 package.json 的样子:

...
"jest": {
    "transform": {
      "^.+\\.js$": "babel-jest"
    }
}
...

这是我的 .babelrc 文件的样子:

{
  "presets": [
    "es2015",
    "react",
    "stage-0"
  ]
}

【讨论】:

    【解决方案2】:

    我相信如果您尝试添加 propTypes,使用 ES7 初始化程序并使用 transform-class-properties,您需要这样做

    static propTypes = {
        name: PropTypes.string.isRequired
    };
    

    原来如此

    import React from 'react';
    import PropTypes from 'prop-types';
    
    export class Demo extends React.Component {
    
        static propTypes = {
            name: PropTypes.string.isRequired
        };
    
        render() {
            return (
                <div className='demo'>{this.props.name}</div>
            );
        }
    
    } 
    

    很确定您不必显式定义props,因为当您从React.Component 扩展时,它是React.Component 的一部分。那或者你可能需要声明constructor,然后调用super(props);

    【讨论】:

    • 您能否确认您的jest 设置正确?您不再需要像 ships with jest now 那样明确地使用 babel-jest。我不确定你的玩笑是否真的正确地转换了 ES7 代码。您可能需要在jest 中指定执行transform-class-properties,尽管这不是必需的,因为您有.babelrc
    • 嗯,关于进程的错误听起来与 webpack 相关。我建议看看this issue?看起来它现在应该支持 webpack 但我看到有些人不得不在他们的 webpack 中编写特定的配置
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-24
    • 2016-03-05
    • 2020-07-24
    • 2021-06-24
    • 2022-06-15
    相关资源
    最近更新 更多