Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

setTimeout needed with enzyme 3.10.0 #2272

Open
2 of 13 tasks
tomraut opened this issue Oct 29, 2019 · 2 comments
Open
2 of 13 tasks

setTimeout needed with enzyme 3.10.0 #2272

tomraut opened this issue Oct 29, 2019 · 2 comments

Comments

@tomraut
Copy link

tomraut commented Oct 29, 2019

Current behavior

I have component including following:

componentDidMount() {
    this.props.errors.observe('errorShow', this.errorShowHandler)
    this.props.errors.observe('errorHide', this.errorHideHandler)
  }

errorShowHandler(errorObject) {
    this.setState({errorMessage: errorObject.code})
}

errorHideHandler() {
    this.setState({errorMessage: undefined})
}

render() {
    if (this.state.errorMessage) {
      return (
        <div id="error">{{ this.state.errorMessage }}</div>
      )
    }
    return null
}

And following way to test this:

describe('when error appears', () => {
    let wrapper, errors
    beforeAll(() => {
      errors = new ObservableModel()
      const strings = {}
      wrapper = mount(<ErrorUI errors={errors}/>)
      errors.update('errorShow', { code: 'TEST_ERROR' } )
      wrapper.update()
    })

    it('should show error code', () => {
      expect(wrapper.text()).toContain('TEST_ERROR')
    })

    describe('when error is hidden', () => {
      beforeAll(() => {
        errors.update('errorHide')
        wrapper.update()
      })

      it('should not show error message', () => {
        expect(wrapper.find('#error').length).toBe(0)
      })
    })

Expected behavior

Second test should work also with enzyme 3.10.0 but instead it says that "Expected 1 to be 0." Same test works with enzyme 3.7.0 - 3.9.0. Modifying test like this makes it also work with 3.10.0:

it('should not show error message', () => {
        setTimeout(function() { expect(wrapper.find('#error').length).toBe(0) }, 500)
 })

Your environment

API

  • shallow
  • mount
  • render

Version

library version
enzyme 3.10.0
react 16.11.0
react-dom 16.11.0
react-test-renderer 16.11.0
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 ( )
@tomraut tomraut changed the title When using Observables for updating component, enxy setTimeout needed with enzyme 3.10.0 Oct 29, 2019
@ljharb
Copy link
Member

ljharb commented Oct 29, 2019

Using setTimeout like that is a race condition. The timing of your "ObservableModel" is not clear, but that is what everything depends on.

@tomraut
Copy link
Author

tomraut commented Oct 30, 2019

@ljharb I forgot to include constructor in my example:

constructor(props) {
    super(props, logger)
    this.errorShowHandler = this.errorShowHandler.bind(this)
    this.errorHideHandler = this.errorHideHandler.bind(this)
  }

So basically whenever I need to show or hide this component, I'm calling for "errors.update('errorShow')" or "errors.update('errorHide')" and the code I have in componentDidMount() does the rest.

I'm not really sure what changes there have been in 3.10.0 compared to earlier versions where test worked correctly but it feels that with 3.10.0 there's just not enough time for component to update itself before test is executed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants