我正在尝试测试一个使用Observables的组件,然后在Observable解析时级联几个函数调用。这是组件的一个版本。
export class NotificationComponent implements OnInit {
private answerSubscription: Subscription;
constructor(public toasterService: ToasterService, private commentService: CommentService) { }
ngOnInit() {
this.answerSubscription = this.commentService.answer$.subscribe(
answer => this.commentComplete(answer));
}
commentComplete(answer) {
this.toasterService.clear(answer.toastId);
let promptAns = this.search(answer.toastId);
}
}
这是我的测试:
class MockToastService {
clear() {}
}
class MockCommentService {
answer$: Observable<any>;
constructor() {
this.answer$ = Observable.of({toastId: '123'});
}
}
describe('NotificationComponent', () => {
let component: NotificationComponent; let fixture: ComponentFixture<NotificationComponent>;
let mockComment = new MockCommentService(); let mockToast = new MockToastService();
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [NotificationComponent, MockToast],
providers: [{ provide: ToasterService, useValue: mockToast },
{ provide: CommentService, useValue: mockComment }]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(NotificationComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should complete notification on answer', () => {
spyOn(component, 'commentComplete'); spyOn(mockToast, 'clear');
expect(component.commentComplete).not.toHaveBeenCalled();
component.ngOnInit();
expect(component.commentComplete).toHaveBeenCalled();
expect(mockToast.clear).toHaveBeenCalled();
});
});
测试在expect(component.commentComplete).toHaveBeenCalled();
上传递,但在expect(mockToast.clear).toHaveBeenCalled()
上失败。从组件中可以看出,toasterService.clear(
应该在commentComplete
之后直接调用,但是,我已经使用调试器,并且在调用clear函数之前正在检查测试条件。
我尝试添加fakeAsync
和tick()
,但我仍然面临着这个问题。知道如何让这个测试的计时工作吗?
答案 0 :(得分:1)
你应该在这里使用假的异步,但是要理解那里没有问题。
你通过spyOn(组件,'commentComplete')伪造'commentComplete'函数,但你需要间谍并完成它的工作。改为'spyOn(component,'commentComplete')。and.callThrough();'
Spies:and.callThrough。通过使用and.callThrough链接间谍,间谍仍将跟踪对它的所有调用,但此外它将委托给实际的实现。
这是应该有效的代码:
it('should complete notification on answer', fakeAsync(() => {
const spyComplete = spyOn(component, 'commentComplete').and.callThrough();
const spyToast = spyOn(mockToast, 'clear');
expect(component.commentComplete).not.toHaveBeenCalled();
component.ngOnInit();
tick();
expect(spyComplete).toHaveBeenCalled();
expect(spyToast).toHaveBeenCalled();
}));