angular - 如何在 Angular/Jasmine 中测试 Filereader.onload 回调函数?

标签 angular testing karma-jasmine filereader

在组件的 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);
    };

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

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

请帮助我测试 onload 回调。我无法为此模拟文件读取器加载,这是正确的吗?

最佳答案

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

将代码包装在 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);
}));

关于angular - 如何在 Angular/Jasmine 中测试 Filereader.onload 回调函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64642547/

相关文章:

javascript - 在 Angular 中使用 Jasmine 使用 *ngIf 指令时,如何对元素是否可见进行单元测试

angularjs - 尝试测试工厂时遇到注入(inject)问题

javascript - Angular 4 : Can't bind to 'ngModel'

java - 如果部分测试花费的时间太长,如何从 JUnit 测试返回到 main 方法

javascript - Angular CLI 在 node_modules 之外添加脚本

python - 在文件顶部导入的模拟函数

sql - 如何在 oracle 数据库中编写参数化查询

jasmine - karma Jasmine 错误: Unexpected request: GET but i'm doing a POST

angular - 在 Angular 9 中失败时如何重试订阅?

angular - 如何避免 Azure AD 256 重定向 uri 限制?