Mar*_*ehl 7 testing rest http karma-runner angular
我目前正在学习 Angular 7(没有使用过任何以前的版本)并且在为服务编写单元测试时遇到了我无法修复的问题。
我有一个从 REST 获取 JSON 并将其解析为一个类的服务。参考 Angular Docs,我使用 HttpClientSpy 编写了一个测试来模拟 404 错误。
发生了什么:测试失败并显示错误消息:“预期的 data.forEach 不是包含‘404’的函数”
因此,服务获取 HttpErrorResponse 作为输入,但尝试将其解析为 map 函数中的常规响应。这失败了, catchError 被调用并且 data.forEach is not a function Error 被抛出。
预期行为:我希望 map() 不会被执行,它应该直接跳到 catchError 函数中。
我是如何修复它的(目前):将以下代码行添加到服务的地图功能使测试工作。
if (data instanceof HttpErrorResponse)
throw new HttpErrorResponse(data);
Run Code Online (Sandbox Code Playgroud)
考试:
it('should throw an error when 404', () => {
const errorResponse = new HttpErrorResponse({
error: '404 error',
status: 404, statusText: 'Not Found'
});
httpClientSpy.get.and.returnValue(of(errorResponse));
service.getComments().subscribe(
fail,
error => expect(error.message).toContain('404')
);
});
Run Code Online (Sandbox Code Playgroud)
服务:
getComments(): Observable<CommentList> {
return this.http
.get('https://jsonplaceholder.typicode.com/comments')
.pipe(
map((data: Array<any>) => {
let t: Array<Comment> = [];
data.forEach(comment => {
if(!('id' in comment) || !('body' in comment) || !('email' in comment) || !('name' in comment))
throw new Error("Could not cast Object returned from REST into comment");
t.push(<Comment>{
id: comment.id,
body: comment.body,
author: comment.email,
title: comment.name,
});
});
return new CommentList(t);
}),
catchError((err: HttpErrorResponse) => {
return throwError(err);
})
);
}
Run Code Online (Sandbox Code Playgroud)
我有什么问题吗?我认为预期的行为是我应该经历的,至少这就是我解释 Angular 文档的方式。
Ant*_*ony 10
迟到的回答,但可能会帮助面临类似问题的人。
错误消息:“expected data.forEach is not a function to contains '404'”是因为of测试用例中的运算符:
httpClientSpy.get.and.returnValue(of(errorResponse));
Run Code Online (Sandbox Code Playgroud)
该of运算符返回一个发出参数的可观察对象。
当您想要返回数据时,这很有用,但当您想要引发 404 错误时,这就没用了。
为了让间谍提出错误,响应应该拒绝而不是解析。
该解决方案使用deferRxJS 运算符以及jasmine.createSpyObj您在示例中使用的方法。
httpClientSpy.get.and.returnValue(of(errorResponse));
Run Code Online (Sandbox Code Playgroud)
最好使用 Angular HttpClientTestingModule来测试HttpClient使用情况。以下示例显示了使用的相同测试HttpClientTestingModule。
import { TestBed } from '@angular/core/testing';
import { HttpErrorResponse } from '@angular/common/http';
import { defer } from 'rxjs';
import { CommentsService } from './comments.service';
// Create async observable error that errors
// after a JS engine turn
export function asyncError<T>(errorObject: any) {
return defer(() => Promise.reject(errorObject));
}
describe('CommentsService', () => {
let httpClientSpy: { get: jasmine.Spy };
let service: CommentsService;
beforeEach(() => {
httpClientSpy = jasmine.createSpyObj('HttpClient', ['get']);
service = new CommentsService(httpClientSpy as any);
});
it('should throw an error when 404', () => {
const errorResponse = new HttpErrorResponse({
error: '404 error',
status: 404,
statusText: 'Not Found'
});
httpClientSpy.get.and.returnValue(asyncError(errorResponse));
service.getComments().subscribe(
data => fail('Should have failed with 404 error'),
(error: HttpErrorResponse) => {
expect(error.status).toEqual(404);
expect(error.error).toContain('404 error');
});
});
});
Run Code Online (Sandbox Code Playgroud)
Angular HTTP 测试文档解释了这种方法。
注意:这些示例是使用 Angular v8 进行测试的。
小智 5
一个迟到的答案,一种稍微不同的方式,但这也有效。
it('should show modal if failed', inject([Router], (mockRouter: Router) => {
const errorResponse = new HttpErrorResponse({
error: { code: `some code`, message: `some message.` },
status: 400,
statusText: 'Bad Request',
});
spyOn(someService, 'methodFromService').and.returnValue(throwError(errorResponse));
expect...
expect...
expect...
}));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11183 次 |
| 最近记录: |