如何在Angular/Jasmine中测试Filereader.onload回调函数?
How can I test the Filereader.onload callback function in Angular/Jasmine?
在我的组件的 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
) 的结果似乎是正确的。
也许将数据转换为 json 的函数的第一行有问题,因为我实际上并没有给函数一个真实的文件。但是,当我尝试提供除模拟 ProgressEvent
以外的任何内容时,它会出错。
请帮助我测试 onload 回调。我不能为此模拟 filereader onload 是否正确?
您不必嘲笑 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);
});
}
要测试新方法,请在成功回调中使用 waitForAsync
和 expect()
:
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);
}));
在我的组件的 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
) 的结果似乎是正确的。
也许将数据转换为 json 的函数的第一行有问题,因为我实际上并没有给函数一个真实的文件。但是,当我尝试提供除模拟 ProgressEvent
以外的任何内容时,它会出错。
请帮助我测试 onload 回调。我不能为此模拟 filereader onload 是否正确?
您不必嘲笑 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);
});
}
要测试新方法,请在成功回调中使用 waitForAsync
和 expect()
:
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);
}));