【问题标题】:mocha + jsdom + React TypeError: Cannot read property 'addEventListener' of undefinedmocha + jsdom + React TypeError:无法读取未定义的属性“addEventListener”
【发布时间】:2015-10-03 07:48:38
【问题描述】:

我刚刚开始使用 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)

任何想法我做错了什么?

【问题讨论】:

  • 你用的是什么版本的jsdom?
  • 我更新了问题以获得所有版本号。
  • 如果从jsdom.jsdom().parentWindow 更改为jsdom.jsdom().defaultView 会发生什么?
  • @AlienBishop:使用defaultView 而不是@limelights 提到的parentWindow 对我有用。
  • 更改为defaultView 只会导致我出现新错误,而我有reported a bug。我认为问题出在我的旧版本 React 上——如果我升级到最新版本的 React,问题就会消失。

标签: reactjs mocha.js jsdom


【解决方案1】:

我发布解决方案以防它对其他人有所帮助。 here 有详细解释,但简而言之:在 Node 的模块加载器加载 React 之前,您必须确保 DOM 已准备好。您可以通过使用 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

【讨论】:

  • 对于使用es2015的人,不要导入jsdom。我花了几个小时试图让它工作,并使用 require 而不是 import 使它工作。我不知道为什么,我很高兴它终于奏效了......
  • 我正在使用带有import 语法的jsdom 就好了。这取决于你的 Babel 配置。
  • 为什么不global.navigator = global.window.navigator
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-08
  • 1970-01-01
  • 2023-04-01
  • 2022-12-31
  • 1970-01-01
  • 2021-09-24
  • 2020-07-10
相关资源
最近更新 更多