Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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 component.

My child component 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.

like image 827
alengel Avatar asked May 04 '15 16:05

alengel


People also ask

What is test each in jest?

Jest Parameterised Testing. A parameterised testing library for Jest inspired by mocha-each. jest-each allows you to provide multiple arguments to your test / describe which results in the test/suite being run once per row of parameters.

What is jest test function?

Save Article. Jest is a Javascript Testing Framework by Facebook. It is used most commonly for unit testing. Unit testing is when you provide input to a unit of code(usually, a function) and match the output with the expected output.


2 Answers

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 components, renderIntoDocument, and simulate the click (checkout the tutorial if not)

describe('#closeModal', function(){
  beforeEach(function(){
    // setup in here to instantiate / render component 
    // 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()
  })
})
like image 34
PhilVarg Avatar answered Nov 15 '22 23:11

PhilVarg


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 component behaves as expected but I couldn't work out how to mock closeModal because I'm testing this specific component 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.

like image 102
alengel Avatar answered Nov 15 '22 22:11

alengel