V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
chenliangngng
V2EX  ›  React

一个简单的 react hooks 功能,请教 jest 单元测试怎么写

  •  
  •   chenliangngng · 2021-10-19 06:43:33 +08:00 · 1851 次点击
    这是一个创建于 1161 天前的主题,其中的信息可能已经有所发展或是发生改变。

    就是实现一个异步操作(比如接口)的 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);
         });
     })
    
    2 条回复    2021-10-20 23:11:59 +08:00
    CodingNaux
        1
    CodingNaux  
       2021-10-19 12:50:43 +08:00   ❤️ 1
    ```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
    chenliangngng
        2
    chenliangngng  
    OP
       2021-10-20 23:11:59 +08:00
    @CodingNaux 感谢大佬
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3250 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 12:28 · PVG 20:28 · LAX 04:28 · JFK 07:28
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.