在行为回调中包装异步moxios调用

时间:2019-06-05 13:31:43

标签: reactjs react-testing-library moxios

我正在尝试使用钩子测试React功能组件。 useEffect钩子调用第三方API,然后在返回时调用setState。

我正在进行测试,但是不断收到警告,表明该组件的更新未包含在行为中。

我的问题是期望值位于moxios.wait承诺中,因此我无法将其包装在act函数中,然后根据该结果进行断言。

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

我已经尝试在react 16.9.0 alpha版本中使用新的async await act函数,以及我在诸如jest setTimers之类的许多github问题中发现的许多建议,但似乎都无法解决该问题。

组件

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

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

警告:测试中的“好处”更新未包含在act(...)中。

在测试时,导致React状态更新的代码应包装在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 个答案:

答案 0 :(得分:0)

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

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