在 act 回调中包装异步 moxios 调用

Wrapping async moxios call in act callback

我正在尝试使用挂钩测试 React 功能组件。 useEffect 挂钩调用第三方 API,然后在 return.

上调用 setState

我进行了测试,但不断收到警告,指出组件更新未包含在 act 中。

我遇到的问题是期望在 moxios.wait promise 中,因此我无法将其包装在 act 函数中,然后断言其结果。

测试通过,但我不知道在 act 函数中包装更新状态的代码可能会导致误报或发现错误。我只是想知道我应该如何测试它。

我已经尝试在 react 16.9.0 alpha 版本中使用新的 async await act 函数以及我在许多 github 问题中发现的大量建议,例如 jest setTimers 和 none似乎可以解决问题。

组件

 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)
    })
  }, [])
}

测试

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()
      })
    })
  })
})

测试通过但我收到以下警告

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)

react 16.9.0 你可以使用 async/await act

您的代码应如下所示

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)
})

我在moxios.wait中使用jest.fn因为它需要回调函数