【问题标题】:Wrapping async moxios call in act callback在行为回调中包装异步 moxios 调用
【发布时间】:2019-06-05 13:31:43
【问题描述】:

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

我的测试工作正常,但不断收到警告说组件的更新未包含在 act 中。

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

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

我已经尝试在 react 16.9.0 alpha 版本中使用新的 async await act 功能,以及我在许多 github 问题(如 jest setTimers)中发现的许多建议,但似乎都没有解决问题。

组件

 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)

【问题讨论】:

  • 这是一个已知问题,请参阅@jonrsharpe 链接的问题。暂时忽略警告是安全的
  • 谢谢@Gpx。我认为应该通过使用 async act 功能来解决这个问题,但这仍然对我不起作用。我认为这可能是 moxios.wait 的工作方式,或者更可能是 react-testing-library 在 react act 方法周围包装了一个 act 方法,并且仍在将其转发到那里导致警告。我想我现在会等这个。感谢帮助家伙。

标签: reactjs react-testing-library moxios


【解决方案1】:

来自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,因为它需要回调函数

【讨论】:

    猜你喜欢
    • 2021-06-26
    • 1970-01-01
    • 1970-01-01
    • 2018-04-06
    • 2011-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多