测试自定义钩子,其中 useEffect 应该被多次调用。

huangapple go评论88阅读模式
英文:

Testing a custom hook where useEffect should be invoked multiple times

问题

我正在尝试测试一个自定义的React钩子,其中包含useEffect,并且我希望在测试中获得对它的引用,因为我必须多次调用它来测试其行为。这涉及到简单的节流:

在测试中,我有一个基本的场景:

但是我想要一个对内部的useEffect的引用,以便能够多次调用并检查回调函数。此外,一个定时器可以触发并检查行为。对于这方面的任何建议将不胜感激!

英文:

I'm trying to test a custom React hook, where i have useEffect inside, and I want a reference to it in the tests as I have to call it multiple times to test the behavior. It's about simple throttling:

  1. export const useThrottleEffect = (effect, deps = [], delay) => {
  2. const lastCall = useRef(0);
  3. useEffect(() => {
  4. const now = new Date().getTime();
  5. if (now - lastCall.current > delay) {
  6. effect();
  7. lastCall.current = now;
  8. }
  9. }, [...deps, delay]);
  10. }

in the test, I have a basic scenario:

  1. let callback;
  2. beforeEach(() => {
  3. callback = jest.fn();
  4. });
  5. test("useThrottleEffect()", () => {
  6. const {result} = renderHook(() => useThrottleEffect(callback, [Date.now()], 1000));
  7. expect(callback).toHaveBeenCalledTimes(1);
  8. result; //?
  9. expect(result.current).toBeUndefined();
  10. });
  11. });

But I what a reference to the inside useEffect in terms to be able to call multiple times and check the callback. Furthermore, a timer could tick and check the behavior. Any tips here would be highly appreciated!

答案1

得分: 1

  1. import { render } from '@testing-library/react';
  2. const Util = ({ number, cb }) => {
  3. useThrottleEffect(cb, [], 2500);
  4. return number;
  5. }
  6. describe('useThrottleEffect', () => {
  7. beforeAll(() => {
  8. jest.useFakeTimers();
  9. });
  10. it('should work', () => {
  11. const cb = jest.fn();
  12. const { rerender } = render(<Util cb={cb} number={1} />);
  13. jest.advanceTimersByTime(1000);
  14. rerender(<Util cb={cb} number={2} />);
  15. jest.advanceTimersByTime(1000);
  16. rerender(<Util cb={cb} number={3} />);
  17. jest.advanceTimersByTime(1000);
  18. rerender(<Util cb={cb} number={4} />);
  19. expect(cb).toHaveBeenCalledTimes(2);
  20. });
  21. }

references:

  1. <details>
  2. <summary>英文:</summary>
  3. You can create an utility component in your test, using the hook as intended to be used in your application.
  4. solution outline (not tested):
  5. ```jsx
  6. import { render } from &#39;@testing-library/react&#39;
  7. const Util = ({ number, cb }) =&gt; {
  8. useThrottleEffect(cb, [], 2500)
  9. return number
  10. }
  11. describe(&#39;useThrottleEffect&#39;, () =&gt; {
  12. beforeAll(() =&gt; {
  13. jest.useFakeTimers()
  14. })
  15. it(&#39;should work&#39;, () =&gt; {
  16. const cb = jest.fn()
  17. const { rerender } = render(&lt;Util cb={cb} number={1} /&gt;)
  18. jest.advanceTimersByTime(1000)
  19. rerender(&lt;Util cb={cb} number={2} /&gt;)
  20. jest.advanceTimersByTime(1000)
  21. rerender(&lt;Util cb={cb} number={3} /&gt;)
  22. jest.advanceTimersByTime(1000)
  23. rerender(&lt;Util cb={cb} number={4} /&gt;)
  24. expect(cb).toHaveBeenCalledTimes(2)
  25. })
  26. })

references:

huangapple
  • 本文由 发表于 2023年2月27日 17:59:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/75578998.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定