测试Jest中的React click事件失败,因为无法应用Jquery - 我该如何测试它?

时间:2015-04-15 14:02:07

标签: jquery reactjs jestjs

我有一个像这样的React类

var React = require('react'),
    $ = require('jquery'),
    AccordionStep = require('./accordion-step');

var Accordion = React.createClass({

  toggleFooter: function(e) {
    var $target = $(e.target),
        $parent = $target.parents('.project-container');

    $target.toggleClass('up down');
    $parent.find('.project-accordion').toggleClass('active');
  },

  render: function() {
    return (
      <div>
        <ul className="project-accordion">
          {this.props.steps.map(function(step, i){
            return <AccordionStep step={step} key={i}/>
          })}
        </ul>
        <span className="footer-info">{this.props.completedSteps} of {this.props.totalSteps} steps completed</span>
        <span className="arrow down mt1" onClick={this.toggleFooter}></span>
      </div>
    )
  }
});

module.exports = Accordion;

我还有一个Jest测试文件,用于检查在单击箭头时是否正确切换了类。

jest.dontMock('../../../dashboard/projects/accordion')
    .dontMock('../../fixtures/projects.fixtures')
    .dontMock('jquery');

describe('Accordion', function() {
  var $ = require('jquery'),
      React = require('react/addons'),
      Accordion = require('../../../dashboard/projects/accordion'),
      AccordionStep = require('../../../dashboard/projects/accordion-step'),
      ProjectFixtures = require('../../fixtures/projects.fixtures'),
      TestUtils = React.addons.TestUtils;

  describe('render', function() {
    var accordion,
        projectFixtures = ProjectFixtures().projects[0],
        steps = projectFixtures.steps;

    beforeEach(function() {
      accordion = TestUtils.renderIntoDocument(
        <div className="project-container">
          <Accordion steps={steps} 
                     completedSteps={projectFixtures.completedSteps} 
                     totalSteps={projectFixtures.totalSteps} />
        </div>
      );
    });

    describe('clicking the arrow icon', function(){
      var arrow;

      beforeEach(function() {
        arrow = TestUtils.findRenderedDOMComponentWithClass(accordion, 'arrow');
      });

      it('should change the arrow to point up when it was clicked', function() {
        TestUtils.Simulate.click(arrow);

        expect(arrow.props.className).toEqual('arrow up mt1');
      });

    });

  });

});

现在我一直在控制台记录toggleFooter函数中发生的事情,我知道该函数正常工作。这些类被切换但测试仍然失败。

我有什么想法可以测试按钮的行为?我想这个问题与测试实际呈现测试DOM的方式有关。我已经尝试使用jQuery断言类正确切换但这也不起作用(我假设由于上述原因)。

任何帮助都会非常感激。

1 个答案:

答案 0 :(得分:2)

您正在通过className直接编辑.arrow dom节点的$target.toggleClass('up down');属性,但不会生成产生它的ReactComponent的道具。

在您的代码中,arrow是一个ReactComponent,而不是一个DOM节点。要查找ReactComponent的DOM节点,请使用React.findDOMNode(component)

React方法是抛弃jQuery执行这样一个简单的任务,而是使用一个标志来更新组件状态,该标志指示手风琴是否处于活动状态。

getInitialState: function() {
  return {
    accordionActive: false
  };
},

toggleFooter: function(e) {
  this.setState({
    accordionActive: !this.state.accordionActive
  });
},

render: function() {
  return (
    <div>
      <ul className={'project-accordion' + (this.state.accordionActive ? ' active' : '')}>
        {this.props.steps.map(function(step, i){
          return <AccordionStep step={step} key={i}/>
        })}
      </ul>
      <span className="footer-info">{this.props.completedSteps} of {this.props.totalSteps} steps completed</span>
      <span className={'arrow mt1 ' + (this.state.accordionActive ? 'up' : 'down')} onClick={this.toggleFooter}></span>
    </div>
  );
}

使用classNames模块,您可以用

替换那些丑陋的className计算
className={classNames('project-accordion', this.state.accordionActive && 'active')}

className={classNames('arrow mt1', this.state.accordionActive ? 'up' : 'down')}

arrow.props.className的值应始终为arrow mt1 uparrow mt1 down

相关问题