I want to test whether my React component can use FileReader
to import the contents of a user-selected file from an <input type="file"/>
element. My code below shows a working component with a broken test.
In my test I'm attempting to use a blob as a substitute for the file because blobs can also be "read" by FileReader
. Is that a valid approach? I also suspect that part of the issue is that reader.onload
is asynchronous and that my test needs to take this into consideration. Do I need a promise somewhere? Alternatively, do I perhaps need to mock FileReader
using jest.fn()
?
I would really prefer to only use the standard React stack. In particular I want to use Jest and Enzyme and not have to use, say, Jasmine or Sinon, etc. However if you know something can't be done with Jest/Enzyme but can be done another way, that might also be helpful.
MyComponent.js:
import React from 'react';
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {fileContents: ''};
this.changeHandler = this.changeHandler.bind(this);
}
changeHandler(evt) {
const reader = new FileReader();
reader.onload = () => {
this.setState({fileContents: reader.result});
console.log('file contents:', this.state.fileContents);
};
reader.readAsText(evt.target.files[0]);
}
render() {
return <input type="file" onChange={this.changeHandler}/>;
}
}
export default MyComponent;
MyComponent.test.js:
import React from 'react'; import {shallow} from 'enzyme'; import MyComponent from './MyComponent';
it('should test handler', () => {
const blob = new Blob(['foo'], {type : 'text/plain'});
shallow(<MyComponent/>).find('input')
.simulate('change', { target: { files: [ blob ] } });
expect(this.state('fileContents')).toBe('foo');
});