Wrapping async moxios call in act callback

ⅰ亾dé卋堺 提交于 2020-01-25 09:16:07

问题


I am trying to test a react functional component using hooks. The useEffect hook makes a call to a third part API which then calls setState on return.

I have the test working but keep getting a warning that an update to the component was not wrapped in act.

The problem I have is that the expectation is inside a moxios.wait promise and therefore I cannot wrap that in an act function and then assert on the result of that.

The test passes but I know not wrapping code that updates state in an act function could lead to false positives or uncovered bugs. I'm just wondering how I should be testing this.

I've tried using the new async await act function in the react 16.9.0 alpha release as well as numerous suggestions I've found in many github issues like jest setTimers and none seem to solve the issue.

The component

 const Benefits = props => {
  const [benefits, setBenefits] = useState([])
  const [editing, setEditing] = useState(false)
  const [editingBenefit, setEditingBenefit] = useState({id: null, name: '', category: ''})

  useEffect(() => {
    axios.get('#someurl')
      .then(response => {
        setBenefits(response.data)
    })
  }, [])
}

The test

describe('Benefits', () => {
  it('fetches the list of benefits from an api and populates the benefits table', (done) => {
    const { rerender } = render(<Benefits />)
    moxios.wait(() => {
      const request = moxios.requests.mostRecent()
      request.respondWith({
        status: 200,
        response: benefits
      }).then(() => {
        expect(document.querySelectorAll('tbody > tr').length).toBe(2)
        done()
      })
    })
  })
})

The test passes but I get the following warning

Warning: An update to Benefits inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser.
    in Benefits (at benefits.spec.js:28)

回答1:


from react 16.9.0 you can use async/await act

Your code should look like this

describe('Benefits', () => {
  it('fetches the list of benefits from an api and populates the benefits table', async() => {
    const { rerender } = render(<Benefits />);

    await moxios.wait(jest.fn);
    await act(async() => {
      const request = moxios.requests.mostRecent()
      await request.respondWith({
        status: 200,
        response: benefits
      });
    });

    expect(document.querySelectorAll('tbody > tr').length).toBe(2)
})

I use jest.fn in moxios.wait because it needs callback function



来源:https://stackoverflow.com/questions/56461528/wrapping-async-moxios-call-in-act-callback

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!