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!
You can create an utility component in your test, using the hook as intended to be used in your application.
solution outline (not tested):
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: