首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何模拟与useRef绑定的钩子中使用的回调函数?

如何模拟与useRef绑定的钩子中使用的回调函数?
EN

Stack Overflow用户
提问于 2021-03-03 06:55:25
回答 1查看 959关注 0票数 1

我试图模拟回调函数(Cb),并希望检查是否调用了1次。

我试过:

代码语言:javascript
复制
    jest.useFakeTimers()
    const cb = (t: number) => `message-${t}`
    const spy = jest.fn(cb)
    // This one also fails.
    // jest.spyOn(React, 'useRef').mockReturnValue({ current: cb });
    const { result } = renderHook(() => useTimer(3, cb))

    await waitFor(() => expect(result.current[0]).toBe(3))
    await waitFor(() => expect(result.current[1]).toBe('message-3'))
    await waitFor(() => expect(spy).toBeCalledTimes(1)) // received 0
代码语言:javascript
复制
const useTimer = (
  startTimeSec: number,
  cb: (currentSeconds: number) => string = (c) => '',
): [number, string] => {
  const [timer, setTimer] = useState(startTimeSec)
  const [intervalTime, setIntervalTime] = useState<null | number>(null)
  const [message, setMessage] = useState<string>('')
  const callback = React.useRef(cb)

  useEffect(() => {
    if (startTimeSec) {
      setTimer(startTimeSec)
      setMessage(callback.current(timer))
    }
  }, [startTimeSec])

  //...

  return [timer, message]
}

有什么想法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-17 03:52:05

您应该将模拟的回调函数spy传递给useTimers而不是cb

此外,让我们回顾一下useRef()的概念

useRef返回一个可变的ref对象,该对象的.current属性初始化为传递的参数(initialValue)。

这意味着模拟的cb函数将是.current属性的值。

例如。

userTimer.ts

代码语言:javascript
复制
import React, { useEffect, useState } from 'react';

const useTimer = (startTimeSec: number, cb: (currentSeconds: number) => string = (c) => ''): [number, string] => {
  const [timer, setTimer] = useState(startTimeSec);
  const [intervalTime, setIntervalTime] = useState<null | number>(null);
  const [message, setMessage] = useState<string>('');
  const callback = React.useRef(cb);

  useEffect(() => {
    if (startTimeSec) {
      setTimer(startTimeSec);
      setMessage(callback.current(timer));
    }
  }, [startTimeSec]);

  return [timer, message];
};

export { useTimer };

useTimer.test.ts

代码语言:javascript
复制
import { waitFor } from '@testing-library/react';
import { renderHook } from '@testing-library/react-hooks';
import { useTimer } from './useTimer';

describe('useTimer', () => {
  it('should pass', async () => {
    const cb = (t: number) => `message-${t}`;
    const spy = jest.fn(cb);
    const { result } = renderHook(() => useTimer(3, spy));

    await waitFor(() => expect(result.current[0]).toBe(3));
    await waitFor(() => expect(result.current[1]).toBe('message-3'));
    await waitFor(() => expect(spy).toBeCalledTimes(1));
  });
});

单元测试结果:

代码语言:javascript
复制
 PASS  examples/66452119/useTimer.test.ts
  useTimer
    ✓ should pass (20 ms)

-------------|---------|----------|---------|---------|-------------------
File         | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------|---------|----------|---------|---------|-------------------
All files    |   92.31 |    33.33 |   66.67 |     100 |                   
 useTimer.ts |   92.31 |    33.33 |   66.67 |     100 | 3-10              
-------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        5.931 s
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66452119

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档