[英]Unit test for method with observables and promise
我有这种方法,我正在尝试为其编写单元测试。 当前的测试只是要以正确的顺序调用 spyOn 方法。
handleSave() {
this.saving = true;
this.presenters.presentLoader({
message: "Uploading..."
});
this.loginService.loginToFirebase().subscribe(() => {
Promise.all(
this.credential.inputs.map((input) => this.putStorageItem(input))
)
.then((url) => {
this.presenters.dismissLoader();
this.presenters.presentAlert({
message: 'Successfully Uploaded Identification.',
buttons: ['Ok']
});
this.presenters.dismissModal(true);
this.saving = false
})
.catch((error) => {
this.presenters.dismissLoader();
this.presenters.presentAlert({
message: 'Something went wrong.'
});
this.saving = false
});
})
}
到目前为止,单元测试适用于 presentLoader 的初始调用,但随后的 dismissLoader(位于 loginToFirebase 可观察对象内,并且 Promise.all 没有被调用(至少在可观察对象和承诺解决之前)
在我之前,我模拟 putStorageItem component.putStorageItem = (item) => Promise.resolve(true);
在里面,我用这个来模拟 loginService。
{
provide: LoginService,
useValue: {
loginToFirebase: () => of(true)
}
},
我目前的测试
it("call handle save should do stuff", () => {
let presenters = TestBed.inject(PresentersService);
spyOn(presenters, 'presentLoader');
spyOn(presenters, 'dismissLoader');
spyOn(presenters, 'presentAlert');
spyOn(presenters, 'dismissModal');
component.handleSave();
expect(presenters.presentLoader).toHaveBeenCalled();
expect(presenters.dismissLoader).toHaveBeenCalled();
expect(presenters.presentAlert).toHaveBeenCalled();
expect(presenters.dismissModal).toHaveBeenCalled();
});
putStorageItem
putStorageItem(input) {
const fileExt = input.file.metadata.name.split('.').slice(-1);
const filepath = ${input.label}.${fileExt}`;
let task;
if(input.file.metadata.isBase64) {
task = this.fireStorage.ref(filepath).put(this.util.b64toBlob(input.file.img), {contentType:input.file.metadata.type, customMetadata:{originalName:input.file.metadata.name}});
} else {
task = this.fireStorage.ref(filepath).put(input.file.img, {contentType:input.file.metadata.type, customMetadata:{originalName:input.file.metadata.name}});
}
input.fileProgress = task.percentageChanges();
return task.then((snapshot) => {
console.log('One success:', input.file)
}).catch((error) => {
console.log('One failed:', input.file, error.message)
});
}
由于您使用的是Observables
和/或promises
,因此您需要使用不同的技术进行测试。 这些技术是:
done
回调async/await
和fixture.whenStable()
waitForAsync
和fixture.whenStable()
fakeAsync
和 Angular 的tick
您还可以阅读更多关于 Angular 中的异步测试的信息。
我最喜欢的是fakeAsync
和tick
,我认为它可以在这种情况下帮助你。
// !! wrap the test in a `fakeAsync` so you have better control of promises
it("call handle save should do stuff", fakeAsync(() => {
let presenters = TestBed.inject(PresentersService);
spyOn(presenters, 'presentLoader');
spyOn(presenters, 'dismissLoader');
spyOn(presenters, 'presentAlert');
spyOn(presenters, 'dismissModal');
component.handleSave();
// !! Call tick() to tell the test that before running the
// statements below the tick,
// ensure the promises in the component code have resolved
// since the expect statements rely on them.
tick();
expect(presenters.presentLoader).toHaveBeenCalled();
expect(presenters.dismissLoader).toHaveBeenCalled();
expect(presenters.presentAlert).toHaveBeenCalled();
expect(presenters.dismissModal).toHaveBeenCalled();
}));
tick
也可用于确保可观察流的subscribe
在继续之前已完成,但我主要将其用于承诺。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.