mocha + jsdom + React TypeError: Cannot read property 'addEventListener' of undefined
mocha + jsdom + React TypeError: Cannot read property 'addEventListener' of undefined
我刚刚开始使用 mocha 2.3.3、jsdom 6.5.1 和 Node.js 4.1.1 对 React 0.10.0 组件进行单元测试。我有这个用于我的单元测试:
var React = require('react/addons');
var TestUtils = React.addons.TestUtils;
var sinon = require('sinon');
var expect = require('chai').expect;
var jsdom = require('jsdom');
var view = require('../student-name-view.js');
describe('The student name view', function() {
var renderedComponent = null;
var nameChangedStub = sinon.stub();
var nameSubmittedStub = sinon.stub();
before(function() {
global.document = jsdom.jsdom('<!doctype html><html><body></body></html>');
global.window = document.parentWindow;
this.renderedComponent = TestUtils.renderIntoDocument(
view({
nameChanged: nameChangedStub,
nameSubmitted: nameSubmittedStub
})
);
this.nameInput = TestUtils.findRenderedDOMComponentWithTag(renderedComponent, 'input').getDOMNode();
});
describe('should notify the controller', function() {
it('when the name field changes', function() {
TestUtils.Simulate.change(this.nameInput);
expect(nameChangedStub.called).to.be.true;
});
});
});
这是我的简单 React 视图:
var React = require('react');
var StudentNameView = React.createClass({
render: function() {
return React.DOM.div({
id: 'name-container',
children: [
React.DOM.p({
children: 'Enter your name'
}),
React.DOM.input({
id: 'nameInput',
onChange: this.props.nameChanged
}),
React.DOM.button({
id: 'doneButton'
})
]
})
}
});
module.exports = StudentNameView;
当我 运行 测试时,我得到这个堆栈跟踪:
TypeError: Cannot read property 'addEventListener' of undefined
at Object.EventListener.listen (node_modules/react/lib/EventListener.js:21:15)
at Object.merge.ensureScrollValueMonitoring (node_modules/react/lib/ReactEventEmitter.js:315:21)
at Object.ReactMount._registerComponent (node_modules/react/lib/ReactMount.js:282:23)
at Object.<anonymous> (node_modules/react/lib/ReactMount.js:305:36)
at Object._renderNewRootComponent (node_modules/react/lib/ReactPerf.js:57:21)
at Object.ReactMount.renderComponent (node_modules/react/lib/ReactMount.js:359:32)
at Object.renderComponent (node_modules/react/lib/ReactPerf.js:57:21)
at Object.ReactTestUtils.renderIntoDocument (node_modules/react/lib/ReactTestUtils.js:57:18)
at Context.<anonymous> (test/student-name-view-test.js:19:44)
知道我做错了什么吗?
我将发布解决方案以防它对其他人有帮助。它在 here 中有详细解释,但简而言之:您必须确保 DOM 在 Node 的模块加载器加载 React 之前准备就绪。您可以通过使用 mocha 的 --require
选项并指定包含 jsdom 设置的文件来强制执行此操作。
就我而言,我在 test
目录中创建了一个名为 setup.js
的文件,其内容如下:
var jsdom = require('jsdom');
global.document = jsdom.jsdom('<!doctype html><html><body></body></html>');
global.window = document.defaultView;
global.navigator = {userAgent: 'node.js'};
现在我的测试使用此命令成功运行:
mocha --require ./test/setup.js
我刚刚开始使用 mocha 2.3.3、jsdom 6.5.1 和 Node.js 4.1.1 对 React 0.10.0 组件进行单元测试。我有这个用于我的单元测试:
var React = require('react/addons');
var TestUtils = React.addons.TestUtils;
var sinon = require('sinon');
var expect = require('chai').expect;
var jsdom = require('jsdom');
var view = require('../student-name-view.js');
describe('The student name view', function() {
var renderedComponent = null;
var nameChangedStub = sinon.stub();
var nameSubmittedStub = sinon.stub();
before(function() {
global.document = jsdom.jsdom('<!doctype html><html><body></body></html>');
global.window = document.parentWindow;
this.renderedComponent = TestUtils.renderIntoDocument(
view({
nameChanged: nameChangedStub,
nameSubmitted: nameSubmittedStub
})
);
this.nameInput = TestUtils.findRenderedDOMComponentWithTag(renderedComponent, 'input').getDOMNode();
});
describe('should notify the controller', function() {
it('when the name field changes', function() {
TestUtils.Simulate.change(this.nameInput);
expect(nameChangedStub.called).to.be.true;
});
});
});
这是我的简单 React 视图:
var React = require('react');
var StudentNameView = React.createClass({
render: function() {
return React.DOM.div({
id: 'name-container',
children: [
React.DOM.p({
children: 'Enter your name'
}),
React.DOM.input({
id: 'nameInput',
onChange: this.props.nameChanged
}),
React.DOM.button({
id: 'doneButton'
})
]
})
}
});
module.exports = StudentNameView;
当我 运行 测试时,我得到这个堆栈跟踪:
TypeError: Cannot read property 'addEventListener' of undefined
at Object.EventListener.listen (node_modules/react/lib/EventListener.js:21:15)
at Object.merge.ensureScrollValueMonitoring (node_modules/react/lib/ReactEventEmitter.js:315:21)
at Object.ReactMount._registerComponent (node_modules/react/lib/ReactMount.js:282:23)
at Object.<anonymous> (node_modules/react/lib/ReactMount.js:305:36)
at Object._renderNewRootComponent (node_modules/react/lib/ReactPerf.js:57:21)
at Object.ReactMount.renderComponent (node_modules/react/lib/ReactMount.js:359:32)
at Object.renderComponent (node_modules/react/lib/ReactPerf.js:57:21)
at Object.ReactTestUtils.renderIntoDocument (node_modules/react/lib/ReactTestUtils.js:57:18)
at Context.<anonymous> (test/student-name-view-test.js:19:44)
知道我做错了什么吗?
我将发布解决方案以防它对其他人有帮助。它在 here 中有详细解释,但简而言之:您必须确保 DOM 在 Node 的模块加载器加载 React 之前准备就绪。您可以通过使用 mocha 的 --require
选项并指定包含 jsdom 设置的文件来强制执行此操作。
就我而言,我在 test
目录中创建了一个名为 setup.js
的文件,其内容如下:
var jsdom = require('jsdom');
global.document = jsdom.jsdom('<!doctype html><html><body></body></html>');
global.window = document.defaultView;
global.navigator = {userAgent: 'node.js'};
现在我的测试使用此命令成功运行:
mocha --require ./test/setup.js