最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - What exactly should I test when calling React's this.props.onClick(this) in Jest? - Stack Overflow

programmeradmin2浏览0评论

I've been writing tests for all my events (and everything else of course) but I'm at a loss on how to test that this.props.onClick(this) was called on a child ponent.

My child ponent has the following code:

closeModal: function() {
  this.props.onClick(this);
},

render: function() {
  return (
    <i className="close-icon" onClick={this.closeModal}></i>
  )
}

and the parent is listening to it like so:

onCloseModal: function() {
  this.replaceState({
    modalStatus: 'hidden'
  });
},

render: function() {
  return (
    <QuestionModal modalStatus={this.state.modalStatus} onClick={this.onCloseModal} />
  )
}

I know how to test the parent's click event and I know how to call the child's button click event in the tests as well but I'm not sure what I should be exactly testing.

If I used Sinon and Jasmine, I would stub the closeModal method and check that it was called. Can I do that with Jest and if so how exactly?

UPDATE

I've tried writing a test based on @PhilVarg's answer but I'm not getting very far as I'm not able to mock closeModal.

Here's my test:

      var closeIcon,
          myMock = jest.genMockFunction();

      form = TestUtils.renderIntoDocument(
        <QuestionForm />
      );
      form.closeModal = myMock;

      closeIcon = TestUtils.findRenderedDOMComponentWithClass(form, 'close-icon');

      TestUtils.Simulate.click(closeIcon);

      expect(form.closeModal).toBeCalled();

The test errors with Expected Function to be called. and closeModal is not mocked but still runs (I have a console log in it at the moment). I've been on it all afternoon but haven't been able to figure it out. Any help would be very appreciated.

I've been writing tests for all my events (and everything else of course) but I'm at a loss on how to test that this.props.onClick(this) was called on a child ponent.

My child ponent has the following code:

closeModal: function() {
  this.props.onClick(this);
},

render: function() {
  return (
    <i className="close-icon" onClick={this.closeModal}></i>
  )
}

and the parent is listening to it like so:

onCloseModal: function() {
  this.replaceState({
    modalStatus: 'hidden'
  });
},

render: function() {
  return (
    <QuestionModal modalStatus={this.state.modalStatus} onClick={this.onCloseModal} />
  )
}

I know how to test the parent's click event and I know how to call the child's button click event in the tests as well but I'm not sure what I should be exactly testing.

If I used Sinon and Jasmine, I would stub the closeModal method and check that it was called. Can I do that with Jest and if so how exactly?

UPDATE

I've tried writing a test based on @PhilVarg's answer but I'm not getting very far as I'm not able to mock closeModal.

Here's my test:

      var closeIcon,
          myMock = jest.genMockFunction();

      form = TestUtils.renderIntoDocument(
        <QuestionForm />
      );
      form.closeModal = myMock;

      closeIcon = TestUtils.findRenderedDOMComponentWithClass(form, 'close-icon');

      TestUtils.Simulate.click(closeIcon);

      expect(form.closeModal).toBeCalled();

The test errors with Expected Function to be called. and closeModal is not mocked but still runs (I have a console log in it at the moment). I've been on it all afternoon but haven't been able to figure it out. Any help would be very appreciated.

Share Improve this question edited May 5, 2015 at 10:53 alengel asked May 4, 2015 at 16:13 alengelalengel 4,9583 gold badges22 silver badges28 bronze badges 2
  • I would just check that the state is replaced. – Jeremy D Commented May 4, 2015 at 16:21
  • Yeah I am checking that on the parent ponent but I also want to test that the click on the child ponent does what it should. – alengel Commented May 5, 2015 at 1:06
Add a ment  | 

3 Answers 3

Reset to default 7

Thanks to some of the suggestions from Phil, I finally figured it out. What I want to test is that closeModal is called when I click the icon. I have already tested that the parent ponent behaves as expected but I couldn't work out how to mock closeModal because I'm testing this specific ponent and by default, this is the only one Jest doesn't mock for me. I could stub it manually but that somehow didn't want to work.

What I've done now is mock this.props.onClick within closeModal and I check that it fires.

Here's how that looks in code:

describe('QuestionForm', function() {
  var onClickFunc,
      form;

  beforeEach(function() {
    onClickFunc = jest.genMockFunction();

    form = TestUtils.renderIntoDocument(
      <QuestionForm onClick={onClickFunc} />
    );
  });

  it('should call closeModal when the icon is clicked', function() {
    var closeIcon = TestUtils.findRenderedDOMComponentWithClass(form, 'close-icon');

    TestUtils.Simulate.click(closeIcon);

    expect(onClickFunc).toBeCalled();
  });

});

I think that sufficiently tests that closeModal behaves as expected.

If you want to check that the function is called you'd want to use jest's toBeCalled function (or toBeCalledWith). Assuming you've done some set up to instantiate the ponents, renderIntoDocument, and simulate the click (checkout the tutorial if not)

describe('#closeModal', function(){
  beforeEach(function(){
    // setup in here to instantiate / render ponent 
    // and simulate the click if the i tag
  })
  it('is called on click', function(){
    expect(questionModal.closeModal).toBeCalled()
  })
})

EDIT: Ok, so after tinkering with it, I was able to get a passing test doing something similar to your original structure. I created a mock function, but instead of doing form.closeModal = mock, I passed the mock into the Question as the onClick prop, and checked if it got called.

describe('#closeModal', function(){
  var mock, form, closeIcon;

  beforeEach(function(){
    mock = jest.genMockFunction();
    form = TestUtils.renderIntoDocument(
      <QuestionForm onClick={ mock } />
    );
    closeIcon = TestUtils.findRenderedDOMComponentWithClass(form, 'close-icon');
    TestUtils.Simulate.click(closeIcon);
  })

  it('is called on click', function(){
    expect(mock).toBeCalled()
  })
})

You could use an asynchronous test. You have to call done() in your onClick handler. If everything is fine the handler will call done() and the test passes. If the handler won't be called the test fails after some time because Jasmine cannot end it.

No need for stubbing or mocking.

it('should click', function(done) {
  function onClick() {
    done();
  }
  var instance = TestUtils.renderIntoDocument(
    <Component onClick={onClick} />
  );
  var button = TestUtils.findRenderedDOMComponentWithTag(instance, 'button');
  var buttonDOM = React.findDOMNode(button);
  React.addons.TestUtils.Simulate.click(buttonDOM);
});
发布评论

评论列表(0)

  1. 暂无评论