Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Test that a click event in React updates the HTML

I've set up some tests of a React component that displays a table using Mocha. I can assert on its initial state but I have a click event which sorts the data that I'd like to test.

If I use React.addons.TestUtils.Simulate.click(theComponent) to try to test the sort.

  • I can see that the event is handled,
  • that the state change is fired
  • the data is sorted before calling setState

but when I assert against the component nothing has changed.

it('sorts the data when the year header is clicked', function() {
    var React = require('react/addons');
    var TestUtils = React.addons.TestUtils;

    var payTable = TestUtils.renderIntoDocument(
        <PayTable payYears={data} />
    );

    var headers = TestUtils.scryRenderedDOMComponentsWithTag(payTable, 'th');
    var yearHeader = headers[0];
    TestUtils.Simulate.click(yearHeader.getDOMNode());

    var columnValues = getYearColumnValues(payTable, TestUtils);
    columnValues.should.match([ 'Year', '1066', '1067', '1068' ]);
});

Do I need to force an update? Re-read the component?

The code is available on Github.

I can test other aspects of the Component but not the Component values after setState

like image 399
Paul D'Ambra Avatar asked Feb 22 '15 23:02

Paul D'Ambra


People also ask

How do you test if a button is clicked in React testing library?

Properly Testing Button Clicks in React Testing Library In order to test button click events in React Testing Library, we need to use the fireEvent API: Once you have the rendered component, you will need to grab the button using screen.

How can you simulate clicking on an element using React testing utilities?

Simulate a Click Event The onClick should pass through to the component's underlying <button /> element because we're spreading ( {... props} ) that props through to it. In the test, we create a ref so that we can pass it to the rendered Button and later to the Simulate. click call.


1 Answers

I had the same issue. The thing is, TestUtils.Simulate.click(yearHeader.getDOMNode()) is making a click on the DOM, which brings about sorting data and DOM manipulation. Even if you use jsDom and not a real dom, this manipulation itself is an async event. So, just by checking the DOM state right after the click event you are making a syncronous call, within which the DOM state has not been changed yet.

The solution is, use a setTimeout with 0 milliseconds timeout, and check the DOM state there. As for you example :

setTimeout(function() {
  var columnValues = getYearColumnValues(payTable, TestUtils);
  columnValues.should.match([ 'Year', '1066', '1067', '1068' ]);
},0)

This would make your DOM update its state and you will be able to test your component.

like image 139
Koustuv Sinha Avatar answered Sep 17 '22 01:09

Koustuv Sinha