【问题标题】:How can I test the Filereader.onload callback function in Angular/Jasmine?如何在 Angular/Jasmine 中测试 Filereader.onload 回调函数?
【发布时间】:2020-11-02 09:02:15
【问题描述】:

在我的组件的ngOnInit 中,我定义了Filereader.onload 回调函数。我找到了几种模拟文件读取器和 onload 的解决方案,但我认为这违背了我测试调用 onload 时回调是否正确执行的目的。 所以我尝试模拟 onload 事件,然后测试回调中的函数是否被调用。

it("should import data on filereader onload event", () => {
 const fileReader = new FileReader();
      let loadEvent: ProgressEvent<FileReader>;
     
      spyOn(fileReader, "onload").and.callThrough();

      spyOn(mockServiceOne, "convertData").and.returnValue(
        mockData
      );
      spyOn(mockServiceTwo, "importData").and.callThrough();

      fileReader.onload(loadEvent);
      fixture.detectChanges();

      expect(fileReader.result).toBeDefined();

      expect(mockServiceOne.convertData).toHaveBeenCalled();
      expect(mockServiceTwo.importData).toHaveBeenCalledTimes(1);
    });
  });

我要测试的功能是这样的:

this.fileReader.onload = (event) => {
      const jsonData = JSON.parse(event.target.result.toString());
      const data = this.serviceOne.convertData(
        jsonData
      );
      this.serviceTwo.importData(data);
    };

我模拟了其中的两个服务和方法。但在测试规范中,它们从未被调用。 然而,需要定义 onload 事件的结果 (event.target.result) 的第一个断言似乎检查为 true。

也许函数中将数据转换为 json 的第一行有问题,因为我实际上并没有给函数一个真实的文件。但是,当我尝试提供除模拟的 ProgressEvent 之外的任何内容时,它会出现错误。

请帮助我测试 onload 回调。我不能为此模拟文件读取器 onload 是否正确?

【问题讨论】:

    标签: angular testing karma-jasmine filereader


    【解决方案1】:

    您不必模拟FileReader。几天前我遇到了同样的问题。一位朋友通过描述代码的异步特性帮助我创建了一个解决方法。

    将您的代码包装在Promise 中并调用其resolve() 回调,传递FileReader 的结果。

    // you would load your file here and return the result in a Promise
    readFileMethod(file: File): Promise<string> {
          return new Promise<string>((resolve) => {
                const fileReader = new FileReader();
                fileReader.onload = (event) => {
                      const jsonData = JSON.parse(event.target.result.toString());
                      const data = this.serviceOne.convertData(jsonData);
                      resolve(data);
                }
                fileReader.readAsText(); // I suppose this is what you called
          });
    }
    

    然后,您的 onInit 将如下所示:

    ngOnInit(): void {
        let file; // init your file however you do
        this.readFileMethod(file).then((data) => {
            this.serviceTwo.importData(data);
        });
    }
    

    要测试新方法,请在成功回调中使用waitForAsyncexpect()

    it('should do whatever with the file', waitForAsync(() => {
        component.readFileMethod(file).then((data) => {
            expect(); // your test here
        });
    }));
    

    要测试您的 onInit,请使用 fakeAsync()tick()

    it('should do whatever with the file', fakeAsync(() => {
        spyOn(mockServiceOne, "convertData").and.returnValue(
            mockData
        );
        spyOn(mockServiceTwo, "importData").and.callThrough();
    
        fixture.detectChanges();
        tick();
        expect(mockServiceOne.convertData).toHaveBeenCalled();
        expect(mockServiceTwo.importData).toHaveBeenCalledTimes(1);
    }));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-18
      • 2018-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多