使用Jest对ES7 React组件进行单元测试

时间:2017-06-28 05:17:19

标签: javascript unit-testing reactjs babeljs jestjs

你如何让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 && ../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:无法读取属性&#39;道具&#39;为null

我还将constructor添加到Demo组件。

2 个答案:

答案 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扩展时它是constructor的一部分。您或者您可能需要声明super(props);,然后致电// Test arrays and pointers #include <stdio.h> // #include <string.h> #define EOL "\n" typedef struct { int useless1; int useless2; } type1; void function1(char* s) { printf("Pointer to string. "); while (*s) putchar(*s++); printf(EOL); } void function2(char* s) { int i=0; printf("Index into string. "); while (s[i]) putchar(s[i++]); printf(EOL); } void functionX1(type1* p, int count) { printf("Pointer to struct." EOL); for (int i=0; i<count; i++) { printf("index: %d useless1: %d" EOL, i, p->useless1); printf("index: %d useless2: %d" EOL, i, p->useless2); p++; } printf(EOL); } void functionX2(type1* p, int count) { printf("Index into array of structures." EOL); for (int i=0; i<count; i++) { printf("index: %d useless1: %d" EOL, i, p[i].useless1); printf("index: %d useless2: %d" EOL, i, p[i].useless2); } printf(EOL); } void getptr1(char* s, char** ss) { *ss = s; } void getptr2(type1* ptr, type1** pptr) { *pptr = ptr; } int main(int argc, char** argv) { // Work with strings of characters char* s; function1( argv[0]); function2( argv[0]); function1(*argv ); function2(*argv ); getptr1(argv[0], &s); function1( s); function2( s); printf("main Pointer to string. "); while (*s) putchar(*s++); printf(EOL); int i=0; printf("main Index into string. "); while (s[i]) putchar(s[i++]); printf(EOL); // Work with array of structures #define count 3 type1 a[count]; int x1 = 123; int x2 = 789000; int kx = 111; for (int i=0; i<count; i++) { a[i].useless1 = x1; a[i].useless2 = x2; x1 += kx; x2 += (kx * 1000); } // functions1(&a , count); Fail // functions2(&a , count); Fail functionX1(&a[0], count); functionX2(&a[0], count); functionX1( a , count); functionX2( a , count); type1* b; getptr2(a, &b); functionX1( b , count); functionX2( b , count); printf("main Pointer to struct." EOL); for (int i=0; i<count; i++) { printf("index: %d useless1: %d" EOL, i, b->useless1); printf("index: %d useless2: %d" EOL, i, b->useless2); b++; } printf(EOL); printf("main Index into array of structures." EOL); for (int i=0; i<count; i++) { printf("index: %d useless1: %d" EOL, i, b[i].useless1); printf("index: %d useless2: %d" EOL, i, b[i].useless2); } printf(EOL); }

答案 1 :(得分: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"预设。
  4. 以下是 package.json 的外观:

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

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

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