Pra*_*vin 2 testing reactjs react-testing-library react-hooks-testing-library
我有一个简单的钩子,可以获取值并将其设置为选项,如下所示:
import Fuse from 'fuse.js'
import React from 'react'
// prefetches options and uses fuzzy search to search on that option
// instead of fetching on each keystroke
export function usePrefetchedOptions<T extends {}>(fetcher: () => Promise<T[]>) {
const [options, setOptions] = React.useState<T[]>([])
React.useEffect(() => {
// fetch options initially
const optionsFetcher = async () => {
try {
const data = await fetcher()
setOptions(data)
} catch (err) {
errorSnack(err)
}
}
optionsFetcher()
}, [])
// const fuseOptions = {
// isCaseSensitive: false,
// keys: ['name'],
// }
// const fuse = new Fuse(options, fuseOptions)
// const dataServiceProxy = (options) => (pattern: string) => {
// // console.error('options inside proxy call', { options })
// const optionsFromSearch = fuse.search(pattern).map((fuzzyResult) => fuzzyResult.item)
// return new Promise((resolve) => resolve(pattern === '' ? options : optionsFromSearch))
// }
return options
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试使用以下代码来测试它:
import { act, renderHook, waitFor } from '@testing-library/react-hooks'
import { Wrappers } from './test-utils'
import { usePrefetchedOptions } from './usePrefetchedOptions'
import React from 'react'
const setup = ({ fetcher }) => {
const {
result: { current },
waitForNextUpdate,
...rest
} = renderHook(() => usePrefetchedOptions(fetcher), { wrapper: Wrappers })
return { current, waitForNextUpdate, ...rest }
}
describe('usePrefetchedOptions', () => {
const mockOptions = [
{
value: 'value1',
text: 'Value one',
},
{
value: 'value2',
text: 'Value two',
},
{
value: 'value3',
text: 'Value three',
},
]
test('searches for appropriate option', async () => {
const fetcher = jest.fn(() => new Promise((resolve) => resolve(mockOptions)))
const { rerender, current: options, waitForNextUpdate } = setup({ fetcher })
await waitFor(() => {
expect(fetcher).toHaveBeenCalled()
})
// async waitForNextUpdate()
expect(options).toHaveLength(3) // returns initial value of empty options = []
})
})
Run Code Online (Sandbox Code Playgroud)
问题是当我尝试在测试结束时断言选项时,它仍然具有初始值[]。但是,如果我将值记录在钩子内,它将返回模拟选项。在 useEffect 以异步方式更新钩子后,如何更新钩子。
waitForNextUpdate我也尝试过在代码中注释的地方使用 using 。它超时并出现以下错误:
Timeout - Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout.Timeout - Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout.Error:
小智 12
一些事情,目前您正在等待fetcher在测试中被调用,但状态更新实际上不是在fetcher调用之后发生,而是在fetcher返回的承诺得到解决之后发生。所以你需要在测试中等待该承诺的解决
result.current此外,您还破坏了首次渲染钩子时的值。该值只是第一次渲染后的副本result.current,之后不会更新。要查询 的当前值,您应该在断言中options查询。result.current
const fetcherPromise = Promise.resolve(mockOptions);
const fetch = jest.fn(() => fetcherPromise);
const { result } = renderHook(() => usePrefetchedOptions(fetcher), { wrappers: Wrappers })
await act(() => fetcherPromise);
expect(result.current).toHaveLength(3)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13701 次 |
| 最近记录: |