enzyme: update() doesn't work for component conditional rendering (based on state)

Current behavior

I’m having a problem regarding a mounted component with conditional rendering based on state changes. Changing the state inside the test updates the state, but not what is rendered, even after invoking wrapper.update() and wrapper.instance().forceUpdate().

Expected behavior

Changing the state inside the test context, and invoking one of (if not both) the wrapper.update() or the wrapper.instance().forceUpdate() should update the component and show the new rendering configuration, since it is based on the current state.

Your environment

API

  • shallow
  • mount
  • render

Version

library version
enzyme ^3.7.0
react ^16.6.1
react-dom ^16.6.1
adapter (below) ^1.6.0

Adapter

  • enzyme-adapter-react-16
  • enzyme-adapter-react-16.3
  • enzyme-adapter-react-16.2
  • enzyme-adapter-react-16.1
  • enzyme-adapter-react-15
  • enzyme-adapter-react-15.4
  • enzyme-adapter-react-14
  • enzyme-adapter-react-13
  • enzyme-adapter-react-helper
  • others ( )

About this issue

  • Original URL
  • State: open
  • Created 5 years ago
  • Reactions: 4
  • Comments: 31 (14 by maintainers)

Most upvoted comments

I would expect that after wrapper.update(), the entire tree would rerender based on the new props/state/etc - so the children should be updated.

One thing that immediately jumps out to me is your use of async/await. The enzyme setState method does not return a Promise, so your use of await is effectively a noop. Try passing a callback as the second argument to setState instead.

@minznerjosh ill do that and look into the issue as a whole.

If somebody was able to open up a PR with a failing testcase for this issue, that’d be amazing.

thanks for the report, everyone.

I’m having this same problem.

Can find <CardBody />, can’t find conditionally rendered child button, even when state preconditions are met. Removing state precondition causes test to pass.

Adding update() or .forceUpdate() doesn’t help.

“react”: “16.8.6” “enzyme”: “3.10.0” “enzyme-adapter-react-16”: “1.14.0”

Test:

    it('displays upload button on Card if file.status === Needs Input', () => {
      const buttons = shallow(
        <FileAccordion
          files={[
            {
              originalFileData: {
                path: 'Myfile.mp3',
                fileStatus: 'Needs Input'
              }
            }
          ]}
        />
      )
        .find(Accordion)
        .find(Card)
        .find(Accordion.Collapse)
        .find(Card.Body)
        .find('button')

      expect(buttons.length).toBe(1)
      expect(buttons.at('0').text()).toBe('Start Upload')
    })

Component:

// ...

<Card.Body>
  {file.status === 'Needs Input' && (<button
    onClick={(e) => {
      // ...
    }}
  >
    Start Upload
  </button>)}
</Card.Body>

// ...