3

我正在阅读reactjs文档,但我很难完全理解它。我希望有更多循序渐进的例子。

我希望能够测试我的组件及其子组件,但我不确定如何创建组件的模拟或实例来测试它们。

代码:

import React from 'react/addons';
import Layout from '../../app/views/layout.js';

var TestUtils = React.addons.TestUtils;

var mockLayout;

describe('Layout (deep copy)', function() {
    beforeEach(function() {
        mockLayout = TestUtils.renderIntoDocument(<Layout />);
    });

    it('is DOM Component', function(done) {
        assert(TestUtils.isDOMComponent(mockLayout));
        done();
    });
});

我收到错误消息,但我不确定这意味着什么:

TypeError: Cannot read property 'getRouteAtDepth' of undefined
    at RouteHandler.createChildRouteHandler (base/spec/views/layout.js:23821:39)
    at RouteHandler.render (base/spec/views/layout.js:23836:27)
    at ReactCompositeComponentMixin._renderValidatedComponentWithoutOwnerOrContext (base/spec/views/layout.js:12011:35)
    at ReactCompositeComponentMixin._renderValidatedComponent (base/spec/views/layout.js:12038:15)
    at ReactPerf.measure.wrapper (base/spec/views/layout.js:3744:22)
    at ReactCompositeComponentMixin.mountComponent (base/spec/views/layout.js:11459:31)
    at ReactPerf.measure.wrapper [as mountComponent] (base/spec/views/layout.js:3744:22)
    at Object.ReactReconciler.mountComponent (base/spec/views/layout.js:3819:36)
    at ReactDOMComponent.ReactMultiChild.Mixin.mountChildren (base/spec/views/layout.js:13014:45)
    at ReactDOMComponent.Mixin._createContentMarkup (base/spec/views/layout.js:12598:33)window.__karma__.result @ debug.html:37(anonymous function) @ adapter.js:98require.register.EventEmitter.emit @ mocha.js:616(anonymous function) @ adapter.js:73require.register.EventEmitter.emit @ mocha.js:611require.register.Runner.fail @ mocha.js:4797require.register.Runner.failHook @ mocha.js:4822(anonymous function) @ mocha.js:4863done @ mocha.js:4518require.register.Runnable.run @ mocha.js:4558next @ mocha.js:4855(anonymous function) @ mocha.js:4876timeslice @ mocha.js:6483
4

1 回答 1

3

测试时不一定要模拟组件。基本上,您只需在测试所述组件时需要您的组件,然后使用反应测试工具将其渲染到 DOM 中。

例如,当这是您的组件时:

// './lib/components/Checkbox.jsx'
var React = require('react');

module.exports = React.createClass({
  getInitialState: function() {
    return { isChecked: false };
  },

  onChange: function() {
    this.setState({ isChecked: !this.state.isChecked });
  },

  render: function() {
    return (
      <label>
        <input
          type="checkbox"
          checked={ this.state.isChecked }
          onChange={ this.onChange }
        />

        { this.state.isChecked ? this.props.labelOn : this.props.labelOff }
      </label>
    );
  }
});

您的测试可能如下所示:

// './test/Checkbox.js'
var React = require('react');
var ReactAddons = require('react/addons').addons;
var TestUtils = ReactAddons.TestUtils;
var expect = require('chai').expect;
var Checkbox = require('../lib/components/Checkbox');

describe('<Checkbox />', function() {
  before(function () {
    this.component = TestUtils.renderIntoDocument(
      <CheckboxWithLabel labelOn="on" labelOff="off" />
    );

    this.label = TestUtils.findRenderedDOMComponentWithTag(this.component, 'label');
    this.input = TestUtils.findRenderedDOMComponentWithTag(this.component, 'input');
  });

  it('component is rendered', function () {
    expect(this.component).to.exist;
  });

  it('component label text equals to "off" by default', function () {
    expect(this.label.getDOMNode().textContent).to.equal('Off');
  });

  it('component label text changes to "on" after click', function() {
    // Simulate change event.
    TestUtils.Simulate.change(input);

    expect(this.label.getDOMNode().textContent).toEqual('On');
  });
}); 

在您的测试中,您可以断言比示例中描述的方式更多,例如,您可以:

  • 断言props正确传递到组件中。
  • 初始化组件时断言state设置正确。
  • 断言state在触发某些操作时正确更改。
  • 断言类名和/或 id 是否设置正确。
  • 断言文本节点的值。

如果您使用的是flux,您甚至可以断言Action Creators是否从组件中正确调用。

唯一需要注意的是,您需要一个 DOM 来测试其中的大部分内容。您可以使用以下方法解决此问题:

就个人而言,因为我不能用 node v0.12.x 运行 jest 并且 jsdom 只支持 v4.0.0 的 io.js,所以我使用mochify。因为我经常使用 mochajsbrowserify,所以 mochify 非常适合我。

于 2015-08-12T17:58:05.287 回答