samedi 23 novembre 2019

Testing React Hooks side effects that depends on other side effects (or other tests)

I have a React Hook that has a simple input and button, and the button is disabled if there is no input, and that same button executes a fetch when it is enabled:

function MyComponent() {
  const [ value, setValue ] = useState('')

  function apiRequest() {
    if (!value) {
      return
    }

    axios.get('url')
      .then(console.log)
      .catch(console.log)
  }

  return (
    <div>
      <input onChange={e => setValue(e.target.value)} value={value} />
      <button disabled={!value} onClick={apiRequest}>
        Submit
      </button>
    </div>
  )
}

I wrote two tests with Enzyme. The first one to test if the disabled prop is correct, and the second one to see if it actually fetches.

it('sets the disabled prop appropriately', function() {
    const wrapper = mount(<MyComponent />)
    const input = wrapper.find('input')
    const btn = wrapper.find('button')
    expect(btn.prop('disabled')).toBeTruthy()
    input.simulate('change', 'abc123')
    expect(btn.prop('disabled')).toBeFalsy()
})

it('fetches on submit', function () {
    const wrapper = mount(<MyComponent />)
    const input = wrapper.find('input')
    input.simulate('change', 'abc123')
    const btn = wrapper.find('button')
    btn.simulate('click')
    expect(axios.get).toHaveBeenCalled()
})

But unfortunately for the second test to work, the button needs to be enabled so text has to be inputted first. So in reality, the second test is also unintentionally testing the disabled prop as well because it will fail (the onClick will not fire) if the disabled prop isn't set correctly.

I followed React's recommended approach of

test React components without relying on their implementation details

which is react-testing-library's core principle, so I'm purely testing side effects. I'm using enzyme instead of that because my team is currently using Enzyme

How would I be able to rewrite my second test so I can only test for the fetch? Thanks in advance.

Aucun commentaire:

Enregistrer un commentaire