我有一个带ModelService
函数的TypeScript edit
:
edit(model: Model): Observable<Model> {
const body = JSON.stringify(model);
return this.http.put(`/models/edit/${model.id}`, body));
}
我有一个带EditComponent
函数的TypeScript edit
,该函数订阅该服务并在得到响应时进行导航:
edit(model: Model): void {
this.service
.edit(model)
.subscribe(() => this.router.navigate([`/models/details/${model.id}`]);
}
测试此组件的edit
函数的最佳方法是什么?
我有一个执行此操作的茉莉花测试:
// Setup
TestBed.configureTestingModule({
declarations: [EditComponent],
providers: [
{
provide: ModelService,
useValue: jasmine.createSpyObj('ModelService', ['edit'])
}
]
});
const fixture = TestBed.createComponent(EditComponent);
const component = fixture.componentInstance;
const modelService = fixture.debugElement.injector.get(ModelService);
fixture.detectChanges();
// Test
it('should call edit', () => {
fakeAsync(() => {
component.edit(model);
expect(modelService.edit).toHaveBeenCalled();
});
});
但是通过此测试,我总是在运行时得到SPEC HAS NO EXPECTATIONS
。我对fakeAsync
的理解是,它可以同步运行,所以我认为这可以工作。
我还尝试使用async
,tick()
和done()
的多种变体,但是在调用组件的变量时,它们给出的消息相同或失败,并且Cannot read property 'subscribe' of undefined
失败edit
功能。
在其他测试中,我已经可以使用return fixture.whenStable().then()
并且可以正常工作(如here所述),但是由于组件函数返回了{{ 1}},而不是Promise。
测试此组件功能的更好方法是什么?
答案 0 :(得分:1)
对于SPEC HAS NO EXPECTATIONS
这似乎不是使用fakeAsync
的正确方法,这就是为什么它没有期望的原因。应该是:
it('should call edit', fakeAsync(() => {
component.edit(model);
expect(modelService.edit).toHaveBeenCalled();
});
无论如何,modelService.edit()
实际上是可以同步预期的呼叫,因为它是在component.edit()
内部调用的。
因此您可以像这样简单地对其进行测试:
it('should call edit', () => {
component.edit(model);
expect(modelService.edit).toHaveBeenCalled();
});
对于Cannot read property 'subscribe' of undefined
因为创建间谍对象没有任何回报。因此,modalService.edit()
返回undefined
并且不能被读取为属性'subscribe'。在这种情况下,我通常通过创建新的Observable或使用of()来存根其结果,并返回此组件可能需要与之交互的值。
jasmine.createSpyObj('ModelService', { edit: of() })