I’m facing a TypeError: Cannot read properties of undefined (reading 'dynamicSheet')
error while unit testing my scrollableComponent. I’m trying to mock the ref container’s scrollWidth and clientWidth to simulate different scrolling scenarios. However, the error persists even after mocking these properties.
Can you provide guidance on how to correctly mock the ref container and resolve this error? Are there any specific considerations or best practices I should follow when testing components with scrollable elements?
This is one of the test case:
const mockSetCurrent = jest.fn();
const setMockRefElement = (node): void => {
const mockRef = {
current: node,
// we need a setter here because it gets called when you
setCurrent: mockSetCurrent(),
// pass a ref to <component ref={ref} />
};
jest.spyOn(React, 'useRef').mockReturnValue(mockRef);
};
it('Expect only right scroll button to be visible', async () => {
const currentScrollableContainer = {
scrollWidth: 2500,
clientWidth: 500,
scrollLeft: 0,
};
// mock scrollableContainerRef
setMockRefElement(currentScrollableContainer);
const { getByLabelText } = render(Initial());
const leftButton = getByLabelText('scroll left');
const rightButton = getByLabelText('scroll right');
expect(leftButton).not.toBeVisible();
expect(rightButton).toBeVisible();
click(rightButton);
expect(mockSetCurrent).toHaveBeenCalled();
// expect to scroll right the distance of clientWidth (by setting scrollLeft to its current value + clientWidth)
expect(mockAnimate).toHaveBeenCalledWith(
'scrollLeft',
currentScrollableContainer,
500,
);
});
Earlier when the component was a class based one this was the code and it was working perfectly:
const setMockRefElement = (node): void => {
const mockRef = {
get current() {
// jest dom elements have no width,
// so mocking a browser situation
return node;
},
// we need a setter here because it gets called when you
// pass a ref to <component ref={ref} />
set current(_value) {
mockSetCurrent();
},
};
jest.spyOn(React, 'createRef').mockReturnValue(mockRef);
};
it('Expect only right scroll button to be visible', async () => {
const currentScrollableContainer = {
scrollWidth: 2500,
clientWidth: 500,
scrollLeft: 0,
};
// mock scrollableContainerRef
setMockRefElement(currentScrollableContainer);
const { getByLabelText } = render(Initial());
const leftButton = getByLabelText('scroll left');
const rightButton = getByLabelText('scroll right');
expect(leftButton).not.toBeVisible();
expect(rightButton).toBeVisible();
click(rightButton);
expect(mockSetCurrent).toHaveBeenCalled();
// expect to scroll right the distance of clientWidth (by setting scrollLeft to its current value + clientWidth)
expect(mockAnimate).toHaveBeenCalledWith(
'scrollLeft',
currentScrollableContainer,
500,
);
});
but when I changed the component to function it was showing rightButton as display: none hence it wasn’t visible.