如何使用 KARMA 对 React JSX ES6 代码进行单元测试?
How to unit test React JSX ES6 code with KARMA?
我用 ES6 编写了我的 React 应用程序。现在我也想用 ES6 编写我的测试。所以这里的挑战是配置业力。
连同 google 我用 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;
}
},
....
我认为此设置应该做什么:1) 将 JSX 编译为 JS,然后 babel
应该将 ES6 转换为 ES5。这与 polyfill
我预计它应该 运行 在 phantomjs 例如。但是不,这是我 运行 时 karma 的输出:
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
app.jsx
的第 35 行包含实际的 JSX 部分。所以,出于某种原因,预处理器似乎没有那么多。如果您对预处理器有任何帮助,我们将不胜感激?
更新:我有这个几乎可以工作的酒。原来我的预处理器应该这样交换
'../app/**/*.jsx': ['babel', 'react'],
'../test/**/*.jsx': ['babel', 'react']
现在,当我 运行 这个时,我得到:
Uncaught ReferenceError: require is not defined
我以为我有一个 polyfill :(
我将 ES6 与 Browserify 和 JSX 一起使用。对于编译,我使用 Babel。以下配置适合我。
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__/组件-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();
});
});
如果您有任何问题,请告诉我。
@zemirico 的回答对我不起作用,而且有点过时了。
这是我自己的设置,您可以将其用于 karma.conf.js
:
...
frameworks: ['jasmine', 'browserify'],
files: [
'src/*',
'tests/*'
],
preprocessors: {
'src/*': ['browserify'],
'tests/*': ['browserify']
},
browserify: {
debug: true,
transform: ['babelify']
}
...
它使用 babelify
而不是 reactify
,并且有其他依赖项。因此,还需要项目根目录中的.babelrc
:
{
presets: ['es2015', 'react']
}
安装程序还需要将以下依赖项包含在 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"
}
用法
在 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>
);
}
}
然后,通过在 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!');
});
});
演示
我用 ES6 编写了我的 React 应用程序。现在我也想用 ES6 编写我的测试。所以这里的挑战是配置业力。
连同 google 我用 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;
}
},
....
我认为此设置应该做什么:1) 将 JSX 编译为 JS,然后 babel
应该将 ES6 转换为 ES5。这与 polyfill
我预计它应该 运行 在 phantomjs 例如。但是不,这是我 运行 时 karma 的输出:
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
app.jsx
的第 35 行包含实际的 JSX 部分。所以,出于某种原因,预处理器似乎没有那么多。如果您对预处理器有任何帮助,我们将不胜感激?
更新:我有这个几乎可以工作的酒。原来我的预处理器应该这样交换
'../app/**/*.jsx': ['babel', 'react'],
'../test/**/*.jsx': ['babel', 'react']
现在,当我 运行 这个时,我得到:
Uncaught ReferenceError: require is not defined
我以为我有一个 polyfill :(
我将 ES6 与 Browserify 和 JSX 一起使用。对于编译,我使用 Babel。以下配置适合我。
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__/组件-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();
});
});
如果您有任何问题,请告诉我。
@zemirico 的回答对我不起作用,而且有点过时了。
这是我自己的设置,您可以将其用于 karma.conf.js
:
...
frameworks: ['jasmine', 'browserify'],
files: [
'src/*',
'tests/*'
],
preprocessors: {
'src/*': ['browserify'],
'tests/*': ['browserify']
},
browserify: {
debug: true,
transform: ['babelify']
}
...
它使用 babelify
而不是 reactify
,并且有其他依赖项。因此,还需要项目根目录中的.babelrc
:
{
presets: ['es2015', 'react']
}
安装程序还需要将以下依赖项包含在 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"
}
用法
在 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>
);
}
}
然后,通过在 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!');
});
});