反应如何测试FileReader onload函数中调用的函数

问题描述 投票:1回答:1

我在组件中有以下代码。我想测试表单的onSubmit,它在reader中调用this.props.onUpload方法。我怎么测试呢?我的期望测试不起作用,我猜是因为this.props.onUpload在reader.onload函数里面?

UploadForm.js

handleSubmit(e) {
    e.preventDefault();

    var inputData = '';
    var file = this.state.file;
    if (file) {
        var reader = new FileReader();
        reader.onload = (function(file) {
            return function(e) {
                inputData = e.target.result;
                this.props.onUpload(inputData);
            };
        })(file).bind(this);
        reader.readAsText(file);            
    }

}

render() {
    return(
        <form onSubmit={this.handleSubmit}>
            <label> Enter File: <br/>
                <input type="file" id="fileinput" onChange={this.handleChange}/>    
            </label>
            <input type="submit" value="Submit" className="btn-upload" />
        </form>
    );
}

UploadForm.test.js

const mockOnUpload = jest.fn();
const file = new File([""], "filename");
const form = shallow(<UploadForm onUpload={mockOnUpload}/>);
const event = {
          preventDefault: jest.fn(),
          target: {files : [file]}
        };

describe('when clicking `upload-file` button', () => {
    beforeEach(() => {
      form.find('#fileinput').simulate('change', event);
      form.find('form').simulate('submit', event);
    });

    it('calls the handleSubmit CallBack', () => {
      expect(mockOnUpload).toHaveBeenCalledWith(input);
    });

});
javascript reactjs tdd jestjs enzyme
1个回答
1
投票

超级好的开始,模拟上传作为道具传递并创建假事件!

我总是喜欢在我自己的工作中遇到这样的测试问题,因为它告诉我我有一个代码味道:如果它不容易测试,可能意味着它更难预测,更难调试,更难解释,&c。

我建议将你的职能分解为更加单一的责任。就目前而言,你的handleSubmit做的不仅仅是处理提交。它还将一个onload函数添加到FileReader的实例,并在该实例上调用readAsText

你的IIFE

function(file) {
  return function(e) {
    inputData = e.target.result;
    this.props.onUpload(inputData);
  };
})(file).bind(this);

可以在组件上拉出箭头功能(照顾bind):

readerOnLoad = file => (e) => {
  this.props.onUpload(e.target.result);
}

(另外,这里需要file作为参数吗?似乎没有使用。)

然后handleSubmit can interact withreaderOnLoad`喜欢;

reader.onload = this.readOnLoad(file);

此时,您可以测试:

  1. handleSubmit如果状态存在,则调用readerOnLoad文件参数。
  2. readerOnLoad,使用文件参数调用,然后调用事件参数,使用事件目标this.props.onLoad值调用result

如果这两个测试都通过,您可以确信您的代码可以使用真实事件,文件和FileReader实例。

看起来你已经了解了如何传入与本机/浏览器对象相匹配的鸭子类型参数(如events),所以只需将它们组合在一起,即可享受精心协作功能的安心!

© www.soinside.com 2019 - 2024. All rights reserved.