【问题标题】:Testing custom hook - not wrapped in act warning测试自定义挂钩 - 未包含在行为警告中
【发布时间】:2022-07-23 05:47:26
【问题描述】:

我正在尝试测试自定义挂钩,但收到此警告消息

console.error node_modules/@testing-library/react-hooks/lib/core/console.js:19 警告:测试中对 TestComponent 的更新未包含在 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. 

这是我的自定义钩子

import { useState, useEffect } from 'react'

import io from 'socket.io-client'

import config from './../../../../config'

const useNotificationsSocket = (user) => {
  const [socket, setSocket] = useState(null)
  const [numUnreadMessages, setNumUnreadMessages] = useState(0)

  const configureSocket = socket => {
    socket.on('connect', () => {
      const data = {
        user: user,
      }
      socket.emit('user joined', data)
    })

    socket && socket.on('messages updated', (data) => {
      //console.log(data)
      setNumUnreadMessages(data.numUnreadMessages)
    })
  }

  useEffect(() => {
    const fetchSocket = async () => {
      const s = await io(config.nSocket.url, {transports: ['websocket']})
      configureSocket(s)
      setSocket(s)
    }

    // Check that user is not an empty object as this causes a crash.
    user && user.Id && fetchSocket()
  }, [user])

  return [socket, numUnreadMessages]
}

export { useNotificationsSocket }

这就是测试

import { renderHook, act } from '@testing-library/react-hooks'

import { useNotificationsSocket } from './../hooks/useNotificationsSocket'

jest.mock('socket.io-client')

describe('useNotificationsSocket', () => {
  it('returns a socket and numUnreadMessages', async () => {
    const user = { Id: '1' }
    const { result } = renderHook(() => useNotificationsSocket(user))
    expect(result).not.toBeNull()
  })
})

我已尝试导入 act 并将代码包装在对 act 的调用中,但是我尝试包装代码时仍然收到警告,并且无法弄清楚在这种情况下我应该如何使用 act。

【问题讨论】:

    标签: testing react-hooks react-custom-hooks


    【解决方案1】:

    你的钩子是异步的,所以你需要等待它的响应:

    describe('useNotificationsSocket', () => {
      it('returns a socket and numUnreadMessages', async () => {
        const user = { Id: '1' }
        const { result } = renderHook(() => useNotificationsSocket(user))
        await waitFor(() => expect(result).not.toBeNull())
      })
    })
    

    另外,如果你定义了多个测试,如果你没有卸载钩子,你可能会遇到你原来的错误。至少这似乎是@testing-library/react v13.3.0 中的行为。您可以通过在测试完成时卸载挂钩来解决此问题:

    describe('useNotificationsSocket', () => {
      it('returns a socket and numUnreadMessages', async () => {
        const user = { Id: '1' }
        const { result, unmount } = renderHook(() => useNotificationsSocket(user))
        await waitFor(() => expect(result).not.toBeNull())
        unmount()
      })
    })
    

    【讨论】:

      猜你喜欢
      • 2019-10-29
      • 1970-01-01
      • 2020-12-13
      • 2020-10-03
      • 1970-01-01
      • 2016-04-14
      • 2020-07-03
      • 2023-01-26
      • 2022-01-03
      相关资源
      最近更新 更多