英文:
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:
export const useThrottleEffect = (effect, deps = [], delay) => {
const lastCall = useRef(0);
useEffect(() => {
const now = new Date().getTime();
if (now - lastCall.current > delay) {
effect();
lastCall.current = now;
}
}, [...deps, delay]);
}
in the test, I have a basic scenario:
let callback;
beforeEach(() => {
callback = jest.fn();
});
test("useThrottleEffect()", () => {
const {result} = renderHook(() => useThrottleEffect(callback, [Date.now()], 1000));
expect(callback).toHaveBeenCalledTimes(1);
result; //?
expect(result.current).toBeUndefined();
});
});
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
import { render } from '@testing-library/react';
const Util = ({ number, cb }) => {
useThrottleEffect(cb, [], 2500);
return number;
}
describe('useThrottleEffect', () => {
beforeAll(() => {
jest.useFakeTimers();
});
it('should work', () => {
const cb = jest.fn();
const { rerender } = render(<Util cb={cb} number={1} />);
jest.advanceTimersByTime(1000);
rerender(<Util cb={cb} number={2} />);
jest.advanceTimersByTime(1000);
rerender(<Util cb={cb} number={3} />);
jest.advanceTimersByTime(1000);
rerender(<Util cb={cb} number={4} />);
expect(cb).toHaveBeenCalledTimes(2);
});
}
references:
- Testing library rerender
- jest Timer Mocks
<details>
<summary>英文:</summary>
You can create an utility component in your test, using the hook as intended to be used in your application.
solution outline (not tested):
```jsx
import { render } from '@testing-library/react'
const Util = ({ number, cb }) => {
useThrottleEffect(cb, [], 2500)
return number
}
describe('useThrottleEffect', () => {
beforeAll(() => {
jest.useFakeTimers()
})
it('should work', () => {
const cb = jest.fn()
const { rerender } = render(<Util cb={cb} number={1} />)
jest.advanceTimersByTime(1000)
rerender(<Util cb={cb} number={2} />)
jest.advanceTimersByTime(1000)
rerender(<Util cb={cb} number={3} />)
jest.advanceTimersByTime(1000)
rerender(<Util cb={cb} number={4} />)
expect(cb).toHaveBeenCalledTimes(2)
})
})
references:
- Testing library rerender
- jest Timer Mocks
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论