2015-04-15 2 views
2

У меня есть класс Реагировать как такТестирование Реакция события клика в Jest не выполняется, потому что JQuery не может быть применен - ​​как я могу его проверить?

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; 

и я также шуткой тестовый файл, который проверяет, был ли переключен класс correcly, когда стрелка была нажата.

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, чтобы утверждать, что классы переключаются правильно, но это также не работает (я предполагаю из-за причины выше).

Любая помощь была бы действительно оценена.

ответ

2

Вы редактируете атрибут className узла .arrow dom напрямую через $target.toggleClass('up down');, но не опоры ReactComponent, которые породили его.

В вашем коде arrow является ReactComponent, а не DOM-узлом. Чтобы найти DOM-узел ReactComponent, используйте React.findDOMNode(component).

Реагирование было бы направлением 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 up или arrow mt1 down.

+0

Это отличное решение и очень эффективный способ! Большое спасибо за то, что показал мне путь;) Действительно оценил и работает как шарм. Bye jQuery, hello React. – alengel