Защо TestUtils.Simulate.click в Jest не работи, когато се използва директно върху React Components?

Да кажем, че имам 2 компонента. Родител, който съдържа дете.

Дъщерният компонент е такъв бутон:

var React = require('react');

var ChildButton = React.createClass({
  onSubmitAnswer: function(e) {
    this.props.onClick(this);
  },

  render: function() {
    return (
      <div className={this.props.visibility}>
          <button onClick={this.onSubmitAnswer}>Click Me</button>
      </div>
    )
  }

});

module.exports = ChildButton;

Той живее в своя родител, който изглежда така:

var React = require('react'),
    ChildButton = require('./face-submit-button');

var ParentComponent = React.createClass({
  onButtonSubmit: function() {
    //Something happens here
  },

  render: function() {
    return (
      <div>
        //Some more components
        <ChildButton text="Submit" onClick={this.onButtonSubmit} />
      </div>
    )
  }

});

module.exports = ParentComponent;

Дотук добре. Всичко работи според очакванията в потребителския интерфейс. Но срещнах някои проблеми в тестовете на Jest, използвайки TestUtils.Simulate.click().

Моят тест за компонента ChildButton е ясен и се държи, както бих очаквал.

jest.dontMock('./child-button');

describe('ChildButton', function() {
  var React = require('react/addons'),
      ChildButton = require('./child-button'),
      TestUtils = React.addons.TestUtils;

  describe('events', function() {
    var button,
        onClickStub;

    beforeEach(function() {
      onClickStub = jest.genMockFn();

      button = TestUtils.renderIntoDocument(
        <ChildButton onClick={onClickStub} />
      );
    });

    it('should call onSubmitAnswer when the button is clicked', function() {
      var buttonTag = TestUtils.findRenderedDOMComponentWithTag(button, 'button');

      TestUtils.Simulate.click(buttonTag);

      expect(onClickStub).toBeCalled();
    });
  });
});

Моят тест за родителския компонент започна да изглежда по същия начин:

jest.dontMock('./parent-component');

describe('ParentComponent', function() {
  var React = require('react/addons'),
      ParentComponent = require('./parent-component'),
      ChildButton = require('./child-button'),
      TestUtils = React.addons.TestUtils;

  describe('events', function() {
    var parent,
        onClickStub;

    beforeEach(function() {
      onClickStub = jest.genMockFn();

      parent = TestUtils.renderIntoDocument(
        <ParentComponent onClick={onClickStub} />
      );
    });

    it('should call onButtonSubmit when a click is triggered', function() {
      var childButton = TestUtils.findRenderedComponentWithType(parent, ChildButton);

      TestUtils.Simulate.click(childButton);

      expect(onClickStub).toBeCalled();
    });
  });
});

Но този тест се проваля. Единствената разлика, която виждам между тези два теста е, че единият използва директно HTML таг и щраква върху него, докато другият задейства щракване върху React компонент. Мога ли да не използвам събитието за щракване върху компонентите на React директно? Правилно ли е предположението ми?

И ако е така, има ли начин да се задейства щракване върху компонентите на React по различен начин в тестовете? Опитах да използвам SimulateNative, но това имаше същия ефект, onClickStub не се извиква при щракване.


person alengel    schedule 14.05.2015    source източник
comment
Звучи сякаш симулираното щракване не избухва до родителя. Ако симулирате щракване върху родител вместо бутона, работи ли според очакванията?   -  person Crob    schedule 14.05.2015
comment
Но искам да тествам дали щракването работи върху бутона, а не върху родителския елемент, който може да има много различни подкомпоненти. Опитах твоето предложение и то все пак се провали.   -  person alengel    schedule 14.05.2015
comment
Но Parent's onClick трябва да се случва винаги, когато се щракне върху нещо в родителя, а не само върху childButton. Не съм сигурен какво друго да опитам, ако симулирането на щракването върху самия родител не работи.   -  person Crob    schedule 14.05.2015
comment
Хм, не съм сигурен, че това предположение е съвсем правилно. Опитвам се да тествам дали събитието onClick на бутона се задейства и на свой ред извиква функцията onButtonSubmit. Начинът, по който го тествах досега, е, че имам мъниче в тази функция и просто проверявам дали е извикана. Но използването на onClick върху бутона директно или самият родител не задейства събитието, следователно моето предположение, че може би събитията onClick не работят върху компонентите на React и трябва да има друг начин.   -  person alengel    schedule 14.05.2015
comment
Така че, тъй като onClick всъщност не трябва да се случва при щракване върху Parent, защо не направите нещо като ‹Parent submitFn={stub} /› и не промените функцията onButtonSubmit, за да извика this.props.submitFn().   -  person Crob    schedule 14.05.2015


Отговори (1)


Понастоящем има отворена грешка за този проблем: Нека ReactTestUtils.Simulate.click работи върху компоненти, които не са dom. Така че отговорът е, че поради грешки можете да използвате Simulate.click само на действителен DOM възел. Така че можете да заобиколите грешката, като получите DOM възела, докато не бъде коригирана.

person Cymen    schedule 28.08.2015