就是实现一个异步操作(比如接口)的 loading 功能
export const useLoading = <T extends (...arg: any) => any>( callback: T, deps: any[] = [], ): [boolean, (...args: any[]) => Promise<ReturnType<T>>] => { const [loading, setLoading] = useState(false); const executor = useCallback(async (...args) => { try { setLoading(true); return await callback(...args); } finally { setLoading(false); } }, deps); return [loading, executor]; };
下面是我写的,第一个 expect 运行对,第二个 expect 想验证函数执行完后 loading 变回 false,但是运行 result.current[0]实际为 true,请教各位大佬
import {renderHook, act} from '@testing-library/react-hooks' describe('useLoading', () => { it('useLoading', async () => { jest.useFakeTimers(); const fn = async () => { return new Promise((resolve, reject) => { setTimeout(() => resolve(true), 1000); }); }; const { result } = renderHook(() => useLoading(fn)); act(() => { const [, executor] = result.current; executor(); jest.advanceTimersByTime(500); }); expect(result.current[0]).toBe(true); act(() => { jest.runAllTicks(); jest.runAllTimers(); }); expect(result.current[0]).toBe(false); }); })
1 CodingNaux 2021-10-19 12:50:43 +08:00 ![]() ```typescript describe("useLoading", () => { it("useLoading", async () => { jest.useFakeTimers(); const fn = async () => { return new Promise((resolve, reject) => { setTimeout(() => resolve(true), 1000); }); }; const { result, waitForNextUpdate } = renderHook(() => useLoading(fn)); act(() => { const [, executor] = result.current; executor(); jest.advanceTimersByTime(500); }); expect(result.current[0]).toBe(true); act(() => { jest.runAllTicks(); jest.runAllTimers(); }); await waitForNextUpdate(); expect(result.current[0]).toBe(false); }); }); ``` waitForNextUpdate,https://react-hooks-testing-library.com/usage/advanced-hooks#async |
2 chenliangngng OP @CodingNaux 感谢大佬 |