我目前正在尝试测试调用http请求服务的函数,然后在订阅部分执行某些操作(调用函数并设置变量)。到目前为止,我的方法是调用函数,我认为将自动调用请求服务,因此将执行订阅部分。但是,我觉得这不是这样做的方式,因为它不起作用。
我想测试的功能:
public trainBot() {
this.isTraining = true;
this.requestsService.trainModel(this.botId, false)
.subscribe(response => {
this.trainingStatus = this.trainingStatusMapping[response['status']];
this.pollTrainingStatus();
});
}
到目前为止我的测试(不起作用)。
it('should poll the training status', () => {
spyOn(component, 'pollTrainingStatus').and.callThrough();
component.trainBot();
fixture.detectChanges();
expect(component.pollTrainingStatus).toHaveBeenCalled();
});
那么,任何人都可以告诉我如何在.subscribe(...部分?
)中测试该部分更新
正如有人建议我将returnValue和async添加到我的测试中。他们仍然没有工作,但现在看起来像这样:
it('should poll the training status', fakeAsync(() => {
component.trainBot();
spyOn(service, 'trainModel').and.returnValue(Observable.of({'status': 'training'}));
spyOn(component, 'pollTrainingStatus').and.callThrough();
fixture.detectChanges();
tick(1);
expect(service.trainModel).toHaveBeenCalled();
expect(component.pollTrainingStatus).toHaveBeenCalled();
}));
错误是相同的
答案 0 :(得分:6)
首先,您需要在运行方法trainBot()之前创建Spies。这应该可以修复你的测试。
it('should poll the training status', () => {
spyOn(service, 'trainModel').and.returnValue(Observable.of({'status': 'training'}));
spyOn(component, 'pollTrainingStatus');
component.trainBot();
expect(service.trainModel).toHaveBeenCalled();
expect(component.pollTrainingStatus).toHaveBeenCalled();
}));
但是,让我们谈谈您的测试策略。
说实话,您正在测试组件,而不是服务,所以您不应该让服务方法通过。
spyOn(service, 'trainModel').and.returnValue(Observable.of({'status': 'training'}));
此外,单元测试应该测试尽可能小的东西。您实际上是在这里测试回调,回调应该是命名方法而不是匿名箭头函数。然后,您可以在其他测试中测试并验证回调的功能。
public trainBot() {
this.isTraining = true;
this.requestsService.trainModel(this.botId, false)
.subscribe(response => this.onTrainbotSuccess(response));
}
public onTrainbotSuccess(response) {
this.trainingStatus = this.trainingStatusMapping[response['status']];
this.pollTrainingStatus();
}
在此测试中,您可以测试响应方法是否被调用
it('should call service.trainModel', () => {
spyOn(service, 'trainModel').and.returnValue(Observable.of({'status': 'training'}));
component.trainBot();
expect(service.trainModel).toHaveBeenCalled();
});
it('should send success responses to onTrainbotSuccess()', () => {
spyOn(component, 'onTrainbotSuccess');
spyOn(service, 'trainModel').and.returnValue(Observable.of({'status': 'training'}));
component.trainBot();
expect(component.onTrainbotSuccess).toHaveBeenCalled();
});
现在我们可以针对成功回调的具体内容编写测试。
it('should poll the training status', () => {
spyOn(component, 'pollTrainingStatus');
component.onTrainbotSuccess({'status': 'training'});
expect(component.pollTrainingStatus).toHaveBeenCalled();
});
答案 1 :(得分:0)
传递给subscribe()
的函数是异步调用的。这意味着您的断言在调用this.pollTrainingStatus()
之前运行。您需要使用async()
or fakeAsync()
utility function。
在代码中可以看起来像这样(如果使用fakeAsync()
):
import { fakeAsync } from '@angular/core/testing';
it('should poll the training status', fakeAsync(() => {
...
expect(component.pollTrainingStatus).toHaveBeenCalled();
}));