I have a react component called FileReader based off Dropzone react component (https://github.com/react-dropzone/react-dropzone). This file reader calls a callback react hook upon dropping a file on the input element of FileReader which looks like so:
import React, { useCallback } from 'react';
import PropTypes from 'prop-types';
import { useDropzone } from 'react-dropzone';
function FilePicker(props) {
const { fileName, setFile, setFileName } = props;
const onDrop = useCallback((acceptedFiles) => {
const reader = new FileReader();
reader.onload = () => {
const binaryFile = reader.result;
setFile(binaryFile);
};
acceptedFiles.forEach((file) => {
setFileName(file.name);
return reader.readAsBinaryString(file);
});
}, [setFile, setFileName]);
const { getRootProps, getInputProps } = useDropzone({ onDrop });
return (
<div data-testid="file-picker" id="file-picker" {...getRootProps()}>
<div className="container-fluid inherit-height">
<input data-testid="file-picker-input" {...getInputProps()} />
<div className="row align-content-center inherit-height">
<p data-testid={fileName} className="text-center" id="file-picker-title">
{fileName !== '' ? fileName : 'Drag n drop a file here, or click to select file' }
</p>
</div>
</div>
</div>
);
}
FilePicker.propTypes = {
fileName: PropTypes.string.isRequired,
setFile: PropTypes.func.isRequired,
setFileName: PropTypes.func.isRequired,
};
export default FilePicker;
Now I am trying to test this component in a way in which I could check if the functions setFile and setFileName have been called appropriately. My test file looks like so:
import React from 'react';
import { render, cleanup, fireEvent, act } from '@testing-library/react';
import 'jest-dom/extend-expect';
import FileReader from './__mocks__/FileReader';
import FilePicker from './FilePicker';
afterEach(cleanup);
describe('React Use S3 Demo', () => {
it('should render file picker', () => {
const mockedFileName = '';
const mockedSetFile = jest.fn();
const mockedSetFileName = jest.fn();
const { rerender, getByTestId, debug } = render(
<FilePicker
fileName={mockedFileName}
setFile={mockedSetFile}
setFileName={mockedSetFileName}
/>,
);
const filePicker = getByTestId('file-picker-input');
act(() => {
fireEvent.drop(filePicker, {
target: {
files: [new File(['(⌐□_□)'], 'chucknorris.png', { type: 'image/png' })],
},
});
});
expect(mockedSetFileName).toHaveBeenCalled();
expect(mockedSetFile).toHaveBeenCalled();
});
});
At first glance it seems like this would work but in reality it doesn't as the FileReader component doesn't seem to call the two functions that are coming down as props. I have tried using the rerender function from '@testing-library/react' but that does not seem to help either. How would you go about testing FileReader in order to have your tests validated upon the setFile and setFileName functions being called?
Thanks!