【问题标题】:Using React.addons.TestUtils to reactjs test components使用 React.addons.TestUtils reactjs 测试组件
【发布时间】:2015-11-05 11:03:03
【问题描述】:

我正在阅读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

【问题讨论】:

    标签: javascript reactjs reactjs-testutils


    【解决方案1】:

    您不必在测试时模拟您的组件。基本上,您只需在测试所述组件时需要您的组件,然后使用 react 测试工具将其渲染到 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 非常适合我。

    【讨论】:

    • 我试图模拟你的一些代码,但我仍然得到同样的错误:dpaste.com/0FPJNF3
    • @Liondancer 我没有看到您粘贴的代码有任何问题,但从您发布的堆栈跟踪来看,getRouteAtDepth 属性似乎正试图从一个不支持的对象访问存在。我猜这发生在 中。如果是这种情况,您需要在测试时将该属性传递给您的组件。
    猜你喜欢
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 2015-02-05
    • 2021-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多