如何在 Angular 中覆盖 HttpErrorResponse
How to coverage HttpErrorResponse in Angular
我正在尝试覆盖 Jasmin 框架的 HttpErrorResponse 代码覆盖率,但它没有覆盖。
组件
onSubmit(form: NgForm) {
if (navigator.onLine) {
const headers = new HttpHeaders().set(InterceptorSkipHeader, '')
this.loginService.login(form.value, headers).subscribe(data => {
const serverData = JSON.parse(JSON.stringify(data));
if (serverData.status == 'success') {
localStorage.setItem(GlobalVariables.AUTHERIZATION_TOEKN, serverData.access_token);
localStorage.setItem(GlobalVariables.USER_ID, serverData.userId);
this.router.navigate([""]);
} else {
this.toast.error(serverData.message, "Fail!");
}
}, (errorResponse: HttpErrorResponse) => {
if (errorResponse.error instanceof ErrorEvent) {
this.toast.error(errorResponse.error.message, "Client Error");
} else {
this.toast.error(errorResponse.error.message, "Server Error");
}
});
} else {
this.toast.error(GlobalVariables.CHECK_INTERNET_CONNECTION, "Fail!");
}
}
测试class
it('Check login component', () => {
const errorResponse = new HttpErrorResponse({
error: '404 error',
status: 404,
statusText: 'Not Found'
});
let testForm = <NgForm>{
value: {
userName: "sample",
password: "sample"
}
};
const headers = new HttpHeaders();
let response;
spyOn(service,'login').and.returnValue(of(errorResponse));
service.login(testForm.value,headers).subscribe(
data => fail('Should have failed with 404 error'),
(error: HttpErrorResponse) => {
expect(error.status).toEqual(404);
expect(error.error).toContain('404 error');
}
);
component.onSubmit(testForm);
});
未覆盖代码
(errorResponse: HttpErrorResponse) => {
if (errorResponse.error instanceof ErrorEvent) {
this.toast.error(errorResponse.error.message, "Client Error");
} else {
this.toast.error(errorResponse.error.message, "Server Error");
}
});
} else {
this.toast.error(GlobalVariables.CHECK_INTERNET_CONNECTION, "Fail!");
}
这是因为在您的测试中调用的是服务,而组件代码中没有涉及的代码。
您需要调用 component.onSubmit
而不是 service.login.subscribe.
您需要对成功案例和错误案例进行单独测试(对每个案例进行两次测试以覆盖 if
和 else
路径)。它们基本上在您模拟 loginService.login
方法的方式上有所不同,当然在预期结果上也有所不同。
对于成功的情况,您模拟loginService.login
如下(if
和[=14=的successResponse
不同] 路径):
spyOn(service,'login').and.returnValue(of(successResponse));
对于error的情况,loginService.login
需要如下所示进行mock:
if
路径...
const errorEvent = <ErrorEvent> { message: 'something bad happened' };
const errorResponse = new HttpErrorResponse({
error: errorEvent
});
spyOn(service,'login').and.returnValue(throwError(errorResponse));
else
路径...
const errorResponse = new HttpErrorResponse({
error: '404 error',
status: 404,
statusText: 'Not Found'
});
spyOn(service,'login').and.returnValue(throwError(errorResponse));
我正在尝试覆盖 Jasmin 框架的 HttpErrorResponse 代码覆盖率,但它没有覆盖。
组件
onSubmit(form: NgForm) {
if (navigator.onLine) {
const headers = new HttpHeaders().set(InterceptorSkipHeader, '')
this.loginService.login(form.value, headers).subscribe(data => {
const serverData = JSON.parse(JSON.stringify(data));
if (serverData.status == 'success') {
localStorage.setItem(GlobalVariables.AUTHERIZATION_TOEKN, serverData.access_token);
localStorage.setItem(GlobalVariables.USER_ID, serverData.userId);
this.router.navigate([""]);
} else {
this.toast.error(serverData.message, "Fail!");
}
}, (errorResponse: HttpErrorResponse) => {
if (errorResponse.error instanceof ErrorEvent) {
this.toast.error(errorResponse.error.message, "Client Error");
} else {
this.toast.error(errorResponse.error.message, "Server Error");
}
});
} else {
this.toast.error(GlobalVariables.CHECK_INTERNET_CONNECTION, "Fail!");
}
}
测试class
it('Check login component', () => {
const errorResponse = new HttpErrorResponse({
error: '404 error',
status: 404,
statusText: 'Not Found'
});
let testForm = <NgForm>{
value: {
userName: "sample",
password: "sample"
}
};
const headers = new HttpHeaders();
let response;
spyOn(service,'login').and.returnValue(of(errorResponse));
service.login(testForm.value,headers).subscribe(
data => fail('Should have failed with 404 error'),
(error: HttpErrorResponse) => {
expect(error.status).toEqual(404);
expect(error.error).toContain('404 error');
}
);
component.onSubmit(testForm);
});
未覆盖代码
(errorResponse: HttpErrorResponse) => {
if (errorResponse.error instanceof ErrorEvent) {
this.toast.error(errorResponse.error.message, "Client Error");
} else {
this.toast.error(errorResponse.error.message, "Server Error");
}
});
} else {
this.toast.error(GlobalVariables.CHECK_INTERNET_CONNECTION, "Fail!");
}
这是因为在您的测试中调用的是服务,而组件代码中没有涉及的代码。
您需要调用 component.onSubmit
而不是 service.login.subscribe.
您需要对成功案例和错误案例进行单独测试(对每个案例进行两次测试以覆盖 if
和 else
路径)。它们基本上在您模拟 loginService.login
方法的方式上有所不同,当然在预期结果上也有所不同。
对于成功的情况,您模拟loginService.login
如下(if
和[=14=的successResponse
不同] 路径):
spyOn(service,'login').and.returnValue(of(successResponse));
对于error的情况,loginService.login
需要如下所示进行mock:
if
路径...
const errorEvent = <ErrorEvent> { message: 'something bad happened' };
const errorResponse = new HttpErrorResponse({
error: errorEvent
});
spyOn(service,'login').and.returnValue(throwError(errorResponse));
else
路径...
const errorResponse = new HttpErrorResponse({
error: '404 error',
status: 404,
statusText: 'Not Found'
});
spyOn(service,'login').and.returnValue(throwError(errorResponse));