'Test onClick of a button is called when there is no props passed down to it using testing library react and jest
I have a component for an upload button which calls the ref of an input when clicked:
import { useRef, FC } from 'react';
import Button from '@mui/lab/LoadingButton';
const UploadButton: FC<UploadButtonProps> = ({
onFileChange,
loading,
text = 'Import File',
accept = '.csv',
disabled = false,
}) => {
const inputRef = useRef<HTMLInputElement>(null);
const onChange = ({ target }: { target: HTMLInputElement }) => {
const { files } = target;
const file = files?.[0];
file && onFileChange?.(file);
target.value = '';
};
return (
<>
<Button
loading={loading}
color="primary"
variant="contained"
disabled={disabled}
onClick={() => {
inputRef.current?.click();
}}
>
{text}
</Button>
<input
aria-label="hidden-upload-input"
ref={inputRef}
style={{
display: 'none',
}}
type="file"
accept={accept}
required
onChange={onChange}
/>
</>
);
};
export default UploadButton;
interface UploadButtonProps {
onFileChange?: (file: File) => void;
loading?: boolean;
text?: string;
accept?: string;
disabled?: boolean;
}
I want to test that when button is clicked its onClick is called or inputRef.current.click is called but I don't know how. I assume that I need to spyOn the onClick prop somehow.
I tried something like this:
it('should call button onClick if being clicked',() => {
const upload = render(<UploadButton text="upload text" />);
const buttonClick = jest.spyOn(upload, 'onClick');
const button = screen.getByText('upload text');
fireEvent.click(button);
expect(button.onclick).toBeCalled();
});
Solution 1:[1]
as a workaround I ended up adding a console log in the onClick function and spyOn it
import { useRef, FC } from 'react';
import Button from '@mui/lab/LoadingButton';
const UploadButton: FC<UploadButtonProps> = ({
onFileChange,
loading,
text = 'Import File',
accept = '.csv',
disabled = false,
}) => {
const inputRef = useRef<HTMLInputElement>(null);
const onChange = ({ target }: { target: HTMLInputElement }) => {
const { files } = target;
const file = files?.[0];
file && onFileChange?.(file);
target.value = '';
};
return (
<>
<Button
loading={loading}
color="primary"
variant="contained"
disabled={disabled}
onClick={() => {
inputRef.current?.click();
console.log('upload');
}}
>
{text}
</Button>
<input
aria-label="hidden-upload-input"
ref={inputRef}
style={{
display: 'none',
}}
type="file"
accept={accept}
required
onChange={onChange}
/>
</>
);
};
export default UploadButton;
interface UploadButtonProps {
onFileChange?: (file: File) => void;
loading?: boolean;
text?: string;
accept?: string;
disabled?: boolean;
}
and test it like this
it('should call button onClick if being clicked', async () => {
render(<UploadButton text="upload text" />);
const spy = jest.spyOn(console, 'log');
const button = screen.getByText('upload text');
fireEvent.click(button);
expect(spy).toBeCalled();
});
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Mohammad K. |
