trevordmiller trevordmiller - 1 year ago 125
React JSX Question

React Testing: Event handlers in React Shallow Rendering unit tests


React Shallow Rendering tests

I am trying to learn how to use the React Shallow Rendering TestUtil and had the tests passing until I added an
event handler to both; It seems that there must be some difference with the
function I am trying to use in
...but I can't figure it out.


How can I get the two highlighted tests in
to pass?

Steps to reproduce

  1. Clone

  2. npm install

  3. npm run dev
    - see that component is working when you click "Lorem Ipsum"

  4. npm run test:watch
    - see that tests are failing

Answer Source

There are a number of issues preventing your tests from passing.

Looking at the test "should be inactive by default":

  1. Accordion.toggle in your test is a property of the Accordion class, and this.toggle in your code is a property of a instance of the Accordion class - so in this case you are comparing two different things. To access the 'instance' method in your test you could replace Accordion.toggle with Accordion.prototype.toggle. Which would work if it were not for this.toggle = this.toggle.bind(this); in your constructor. Which leads us to the second point.

  2. When you call .bind() on a function it creates a new function at runtime - so you can't compare it to the original Accordion.prototype.toggle. The only way to work around this is to pull the "bound" function out of the result from render:

    let toggle = result.props.children[0].props.onClick;
    assert.deepEqual(result.props.children, [
      <a onClick={toggle}>This is a summary</a>,
      <p style={{display: 'none'}}>This is some details</p>

As for your second failing test "should become active when clicked":

  1. You try calling result.props.onClick() which does not exist. You meant to call result.props.children[0].props.onClick();

  2. There is a bug in React that requires a global "document" variable to be declared when calling setState with shallow rendering - how to work around this in every circumstance is beyond the scope of this question, but a quick work around to get your tests passing is to add global.document = {}; right before you call the onClick method. In other words where your original test had:


    Should now say:

    global.document = {};

    See the section "Fixing Broken setState()" on this page and this react issue.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download