首页 > 解决方案 > 如何模拟 FileReader 的失败

问题描述

我有一个创建FileReader. 在该函数中,我还设置了loaderror事件处理程序

handleFileSelect(files:ArrayLike<File>){
...
      let reader = new FileReader()
      reader.onload = this.handleReaderLoaded;
      reader.onerror = this.handleReaderError;


      reader.readAsDataURL(file);
    }
  }

我想进行单元测试以handleFileSelect正确设置错误处理程序并且如果失败handleReaderError则调用错误处理程序 () 。FileReader但我不知道如何使FileReader失败。

到目前为止我写的规范是

fit('should call error handler when file doesn\'t get loaded successfully', (done) => {
    let newPracticeQuestionComponent = component;

    let file1 = new File(["foo1"], "foo1.txt");
    /*
    File reader will load the file asynchronously.
    The `done` method of `Jasmine` makes `Jasmine` wait
    When handleReaderError is called, call a fake function and within it call done
     */
    spyOn(newPracticeQuestionComponent,'handleReaderError').and.callFake(function(event:FileReaderProgressEvent){
      console.log("called fake implementation of handleReaderError ",event);
      expect(event.type).toEqual("abort");
      done();
    });

    newPracticeQuestionComponent.handleFileSelect([file1]);
//I SHOULD SIMULATE FILEREADER ERROR HERE BUT HOW??

  });

标签: typescriptjasminefilereader

解决方案


已经说过我们可以模拟readAsDataURL方法并从中分派错误事件。但是您的 reader 是函数中的局部变量handleFileSelect。为了访问阅读器,我们可以模拟FileReader构造函数并控制创建的文件阅读器实例。这里我使用sinon来模拟:

// in your test:
...

// This is the reader instance that we have access
const reader = new FileReader()

// We throw an error in readAsArrayBuffer method of that instance
reader.readAsArrayBuffer = () => {
  reader.dispatchEvent(new Event('error'))
}

// Now make the constructor return our instance
sinon.stub(window, 'FileReader').returns(r)

// Now make your calls and assertions
...    

// Don't forget to restore the original constructor at the end
window.FileReader.restore()


推荐阅读