Reputation: 4081
How can I mock the following hook in Jest?
I use this hook in another hook, When I want to test the other hook, I need to mock useScrollDetect
and remove the throttle
part, than means I need to immediately call onScroll
on scroll events
For educational purpose, I don't want to mock lodash.throttle
import { useCallback, useEffect, useRef } from 'react';
import { throttle } from 'lodash';
/**
* A hook to listen to the scroll event
* @param onScroll Scroll listener
* @param throttleTime Throttling time of the events
* @param enable Enable or disable the listener
*/
const useScrollDetect = (
onScroll: (e: Event) => void,
throttleTime = 100,
enable = true
) => {
const handleScrollThrottle = useCallback(
throttle(onScroll, throttleTime, {
leading: false,
trailing: true,
}),
[onScroll, throttleTime]
);
useEffect(() => {
if (enable) {
window.addEventListener('scroll', handleScrollThrottle, {
passive: true,
});
}
return () => {
if (enable) {
window.removeEventListener('scroll', handleScrollThrottle);
}
};
}, [enable, handleScrollThrottle]);
};
export { useScrollDetect };
Upvotes: 1
Views: 2571
Reputation: 39
You could try to mock it via this approach:
// your test file
import * as hooks from './use-scroll-detect.ts';
// typescript will highlight useScrollDetect from jest.spyOn and hooks object
jest.spyOn(hooks, 'useScrollDetect').mockImplementation((
onScroll: (e: Event) => void,
throttleTime: number,
enable: boolean
) => {
const mockEvent = {}; // pass necessary values into the object
onScroll(mockEvent); // call your mock fn with some info
});
Or you can mock only your throttle
function from lodash:
jest.mock('lodash', () => ({
...jest.requireActual('lodash'),
throttle: jest.fn().mockImplementation((onScroll: (e: Event) => void) => {
onScroll(new Event('scroll'));
})
}))
fireEvent.scroll(screen.getByText('bla bla')) // put your own function from screen to find element for scrolling
Upvotes: 2