I'm trying to write a unit test for one of my React components written in TS:
import React, { useContext } from 'react';
import Lottie from 'lottie-react-web';
import { ConfigContext } from '../ConfigProvider';
import type { UIKitFC } from '../../types/react-extensions';
// interfaces
export interface LoadingOverlayProps {
size: 'large' | 'medium' | 'small';
testId?: string;
}
interface LoaderProps {
size: 'large' | 'medium' | 'small';
}
const G3Loader: React.FC<LoaderProps> = ({ size }) => {
const options = { animationData };
const pxSize =
size === 'small' ? '100px' : size === 'medium' ? '200px' : '300px';
const height = pxSize,
width = pxSize;
return (
<div className="loader-container">
<Lottie options={options} height={height} width={width} />
<div className="loader__loading-txt">
<div>
<h4>Loading...</h4>
</div>
</div>
</div>
);
};
/**
* Description of Loading Overlay component
*/
export const LoadingOverlay: UIKitFC<LoadingOverlayProps> = (props) => {
const { testId } = props;
const { namespace } = useContext(ConfigContext);
const { baseClassName } = LoadingOverlay.constants;
const componentClassName = `${namespace}-${baseClassName}`;
const componentTestId = testId || `${namespace}-${baseClassName}`;
return (
<div id={componentTestId} className={componentClassName}>
<G3Loader size={props.size} />
</div>
);
};
LoadingOverlay.constants = {
baseClassName: 'loadingOverlay',
};
LoadingOverlay.defaultProps = {
testId: 'loadingOverlay',
};
export default LoadingOverlay;
The component uses an imported module "Lottie" for some animation, but I'm not interested in testing it, I just want to test my component and its props.
The problem is, when I run my unit test, I get an error: Error: Not implemented: HTMLCanvasElement.prototype.getContext (without installing the canvas npm package)
After some research, I've concluded that the error is caused by the Lottie import so I would like to mock it for the purpose of my test. I'm using Mocha and Sinon's stub functionality to try and mock the library import, but the same error persists, making me feel like I'm not stubbing the module out correctly. Here's my latest attempt at a unit test:
import React from 'react';
import * as Lottie from 'lottie-react-web';
import { render } from '@testing-library/react';
import { expect } from 'chai';
import * as sinon from 'sinon';
import LoadingOverlay from '../src/components/LoadingOverlay';
const TEST_ID = 'the-test-id';
const FakeLottie: React.FC = (props) => {
return <div>{props}</div>;
};
describe('Loading Overlay', () => {
// beforeEach(function () {
// sinon.stub(Lottie, 'default').callsFake((props) => FakeLottie(props));
// });
console.log('11111');
it('should have a test ID', () => {
sinon.stub(Lottie, 'default').callsFake((props) => FakeLottie(props));
console.log(Lottie);
const { getByTestId, debug } = render(
<LoadingOverlay testId={TEST_ID} size="small" />
);
debug();
expect(getByTestId(TEST_ID)).to.not.equal(null);
});
});
I'm not really sure what else to try, unit tests are not my forte... If anyone can help, that would be great.