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.
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
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With