我有一个loading
状态,以及一个循环该状态的函数,在状态之间获取和设置数据:
async function getData(fetch) {
setLoading(true);
setData(await fetch());
setLoading(false);
}
使用await act()
将等待状态稳定,这意味着对loading === true
的任何Assert都将失败。
it('cycles loading',async () => {
// ... renderHook
await act(getData)
await waitFor(() => expect(result.current.loading).toBe(true)) // This always fails
await waitFor(() => expect(result.current.data).toBe(newData)) // This passes
await waitFor(() => expect(result.current.loading).toBe(false))// This passes
}
让它工作的一个方法是不使用act()
it('cycles loading',await () => {
// ... renderHook
getData(); // Gives act warning
await waitFor(() => expect(result.current.loading).toBe(true)) // This passes
await waitFor(() => expect(result.current.data).toBe(newData)) // This passes
await waitFor(() => expect(result.current.loading).toBe(false))// This passes
}
我试着使用promises,同时将call包含在一个act中,并在act中Assert:
it('cycles loading',async () => {
// ... renderHook
let resolve;
const fetch = () => new Promise(res => {resolve = res})
await act(() => {
getData();
waitFor(() => expect(result.current.loading).toBe(true)) // This passes
resolve(newData);
}
await waitFor(() => expect(result.current.data).toBe(newData)) // This passes
await waitFor(() => expect(result.current.loading).toBe(false))// This passes
// Still getting act error...
}
这些测试在语义上是100%正确的,但是它们代表了我试图让这种类型的测试工作的迭代。
预过帐编辑
在又尝试了一次迭代之后,我让它工作了,但是我不知道为什么,这是一个工作的版本,任何关于为什么的见解都将非常感谢。
我所做的是将承诺的分辨率从act()
中移除
it('cycles loading',async () => {
// ... renderHook
let resolve;
const fetch = () => new Promise(res => {resolve = res})
await act(() => {
getData();
waitFor(() => expect(result.current.loading).toBe(true)) // This passes
}
resolve(newData);
await waitFor(() => expect(result.current.data).toBe(newData)) // This passes
await waitFor(() => expect(result.current.loading).toBe(false))// This passes
}
1条答案
按热度按时间gojuced71#
您的
getData
实现在异步与同步处理逻辑方面存在缺陷。应该这样做:
然后你所有的测试都变得简单了,你只需要等待一个承诺,仅此而已。而且拒绝不会影响状态。