【问题标题】:React how to test function called in FileReader onload function反应如何测试 FileReader onload 函数中调用的函数
【发布时间】:2018-06-06 09:11:50
【问题描述】:

我在一个组件中有以下代码。我想测试表单的 onSubmit,它在阅读器中调用 this.props.onUpload 方法。 我该如何测试呢? 我的期望测试不起作用,我猜这是因为 this.props.onUpload 在 reader.onload 函数中?

上传表单.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>
    );
}

上传表单.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】:

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

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

    我建议将您的职能分解为更加单一的责任。就目前而言,您的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,使用文件参数和事件参数调用,使用事件目标result 值调用this.props.onLoad

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

    看起来您已经了解如何传递与本机/浏览器对象匹配的鸭子类型参数(如 events),所以只需将它们放在一起,享受您良好协作的功能所带来的安心!

    【讨论】:

    • 谢谢!一旦我能够做到,我会尝试一下
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-21
    • 2020-08-17
    相关资源
    最近更新 更多