简体   繁体   English

如何使用KARMA对React JSX ES6代码进行单元测试?

[英]How to unit test React JSX ES6 code with KARMA?

I've written my React app with ES6. 我用ES6编写了我的React应用程序。 Now I would like to write my tests also with ES6. 现在我想用ES6编写我的测试。 So the challenge here is to configure karma. 所以这里的挑战是配置业力。

Together with google I came this far with karma.config.js (I've omitted parts of the config file which are the same!): 和谷歌一起,我带着karma.config.js走了这么远(我省略了配置文件的相同部分!):

...
files: [
  '../node_modules/karma-babel-preprocessor/node_modules/babel-core/browser-polyfill.js',
  '../app/**/*.jsx',
  '../test/**/*.jsx'],

 preprocessors: {
  'app/**/*.jsx': ['react-jsx', 'babel'],
  'test/**/*.jsx': ['react-jsx', 'babel']
 },
 'babelPreprocessor': {
  options: {
    sourceMap: 'inline'
  },
  filename: function(file) {
    return file.originalPath.replace(/\.jsx$/, '.es5.js');
  },
  sourceFileName: function(file) {
    return file.originalPath;
  }
},
....

What I think this setup should do: 1) compile the JSX to JS and next babel should transform ES6 to ES5. 我认为这个设置应该做什么:1)将JSX编译为JS,下一个babel应该将ES6转换为ES5。 This together with the polyfill I expected it should run in phantomjs for example. 这与一起polyfill我预计应该在phantomjs例如运行。 But no, here is the output from karma when I run it: 但不,这是我运行时来自业力的输出:

PhantomJS 1.9.8 (Mac OS X) ERROR
    SyntaxError: Parse error
    at Projects/ES6/app/js/app.jsx:35
    PhantomJS 1.9.8 (Mac OS X): Executed 0 of 0 ERROR (0.027 secs / 0 secs)
    [20:36:59] Karma has exited with 1

Line 35 of app.jsx contains the actual JSX part. app.jsx第35 app.jsx包含实际的JSX部分。 So, for some reason the preprocessors seems to do not so much. 因此,出于某种原因,预处理器似乎并没有那么多。 Any help with the preprocessors would be appreciated ? 任何有关预处理器的帮助都会受到赞赏吗?

UPDATE: I have this almost working nog. 更新:我有这个几乎工作的nog。 Turns out that the preprocessors I had should be swapped like this 事实证明我应该像这样交换我的预处理器

 '../app/**/*.jsx': ['babel', 'react'], 
 '../test/**/*.jsx': ['babel', 'react']

Now, when I run this, I get: 现在,当我运行这个时,我得到:

Uncaught ReferenceError: require is not defined

I thought I had a polyfill for that :( 我以为我有一个polyfill :(

I use ES6 with Browserify and JSX. 我在浏览器和JSX中使用ES6。 For compilation I use Babel. 对于编译我使用Babel。 The following configuration works for me. 以下配置适用于我。

karma.conf.js karma.conf.js

...
frameworks: ['browserify', 'jasmine'],
files: [
  'Component.js',                     // replace with your component
  '__tests__/Component-test.js'
],
preprocessors: {
  'Component.js': 'browserify',
  './__tests__/Component-test.js': 'browserify'
},
browserify : {
  transform : ['babelify']
},
...

__tests__/Component-test.js __tests __ /组件的test.js

var React = require('react/addons');
var TestUtils = React.addons.TestUtils;
var Component = require('../Component.js');

describe('Component', () => {

  it('should work', () => {
    var component = <Component />;
    TestUtils.renderIntoDocument(component);
    expect(component).toBeTruthy();
  });

});

If you have any questions let me know. 如果您有任何问题,请告诉我。

@zemirico answer did not work for me and is slightly outdated. @zemirico的回答对我不起作用,有点过时了。

Here is my own setup that you can use for karma.conf.js : 这是我自己的设置,你可以用于karma.conf.js

...
frameworks: ['jasmine', 'browserify'],

files: [
    'src/*',
    'tests/*'
],

preprocessors: {
    'src/*': ['browserify'],
    'tests/*': ['browserify']
},

browserify: {
    debug: true,
    transform: ['babelify']
}
...

It uses babelify instead of reactify , and has other dependencies. 它使用babelify而不是reactify ,并具有其他依赖性。 Thus, .babelrc in the project root is also needed: 因此,还需要项目根目录中的.babelrc

{
  presets: ['es2015', 'react']
}

The setup also requires the dependencies below to be included in package.json file: 该设置还要求以下依赖项包含在package.json文件中:

  "devDependencies": {
    "babel-preset-react": "^6.5.0",
    "babelify": "^7.2.0",
    "browserify": "^13.0.0",
    "jasmine-core": "^2.4.1",
    "karma": "^0.13.22",
    "karma-browserify": "^5.0.3",
    "karma-chrome-launcher": "^0.2.3",
    "karma-jasmine": "^0.3.8",
    "watchify": "^3.7.0",
    "babel-preset-es2015": "^6.6.0",
    "react": "^15.0.1",
    "react-addons-test-utils": "^15.0.1",
    "react-dom": "^15.0.1"
  }

Usage 用法

Create a new React component in src/my-element.jsx : src/my-element.jsx创建一个新的React组件:

import React from 'react';

export default class MyElement extends React.Component {

  constructor(props) {
    super(props);
    this.state = {isActive: false};

    this.onClick = this.onClick.bind(this);
  }

  onClick() {
    this.setState({isActive: !this.state.isActive});
  }

  render() {
    return (
      <div onClick={this.onClick}>{this.state.isActive ? "I am active!" : "I am not active :("}</div>
    );
  }
}

Then, test it as such by creating spec in tests/my-element-spec.js : 然后,通过在tests/my-element-spec.js创建spec来tests/my-element-spec.js

import React from 'react';
import ReactDOM from 'react-dom';
import TestUtils from 'react-addons-test-utils';
import MyElement from '../src/my-element.jsx';

describe('MyElement', () => {

  // Render a checkbox with label in the document
  const element = TestUtils.renderIntoDocument(<MyElement />);
  const elementNode = ReactDOM.findDOMNode(element);

  it('verity correct default text', () => {
    expect(elementNode.textContent).toEqual('I am not active :(');
  });

  it ('verify text has been changed successfuly after click', () => {
    // Simulate a click and verify that it is now On
    TestUtils.Simulate.click(elementNode);

    // Verify text has been changed successfully
    expect(elementNode.textContent).toEqual('I am active!');
  });
});

Demo 演示

Working example on GitHub . GitHub上的工作示例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM