使用catch和_throw错误逻辑测试Angular 4 HttpTestingController

时间:2017-10-12 20:25:49

标签: angular unit-testing karma-jasmine

我使用 HttpClient 使用POST请求服务,如果服务器响应并且错误我需要捕获它格式化消息并重新抛出它。我试图测试这种情况,但未能模拟测试。 HttpTestingController没有发回我的自定义错误消息,也没有在服务上捕获它并重新抛出它,是什么方法这样做

服务代码:

ll=df.groupby(level='Id').apply(lambda x : x.set_index('product').T.to_dict(orient='records')).tolist()


import operator
import functools
functools.reduce(operator.concat, ll)

Out[130]: 
[{"'0.5L'": 4, "'1.5L'": 4, "'407'": 8, "'409'": 41},
 {"'SCHWEPPES'": 6, "'TONIC1L'": 4}]

现在测试

 login(credentials: LoginPayload): Observable<LoginSuccessPayload> {

      return this.http.post<LoginSuccessPayload>('/api/auth/signin', credentials)
             .map(res => {authUser: res.user})
             .catch((error: HttpErrorResponse) => {
                if (error.message) {
                    return _throw(error);
                }
                return _throw({message: 'Notification.LoginError'});
             });

 }

3 个答案:

答案 0 :(得分:1)

我知道我已经迟到了,但我想我无论如何都要回答这个问题,对于那些像我一样偶然发现这一点的人。我发现在这个错误情况下angular.io上的完整lack of documentation是疯了。 &#34;自己弄清楚&#34;,我想?

无论如何......我采取的方法是完全避免使用.error(),因为它似乎不像使用.flush()那样容易,而文档确实state它可以用于成功和不成功的回复。

以下是我如何更新代码以使用flush:

it('should format the error message', (done) => {
    const credentials = {userName: 'bob', password: '123'} as LoginPayload;
    const mockErrorResponse = {message: 'failed to login'} ;

    authService.login(credentials).subscribe(() => {}, err => {
        // NOTE: err.error.message
        expect(err.error.message).toEqual(mockErrorResponse.message);
        done();
    });

    const req = httpMock.expectOne('/api/auth/signin');
    req.flush({message: mockErrorResponse.message}, {status: 400, statusText: ''});

    httpMock.verify();
});

HttpClient@angular/common/http而非Http中的@angular/httperr.error进行此更新的一个令人烦恼的部分是错误消息现在是{{1}的属性在subscribe()而不是err本身。

因此,如果您和我一样,并且您要从一个升级到另一个,那么对err.message的所有引用现在都必须更新为err.error.message。我希望这会有所帮助。

答案 1 :(得分:0)

我有一些建议可供我使用。

首先我要替换它:

authService = TestBed.get(AuthService);
httpMock = TestBed.get(HttpTestingController);

用这个:

const testBed = getTestBed();
authService = testBed.get(AuthService);
httpMock = testBed.get(HttpTestingController);

我认为这里的重点是您无法真正访问Testbed。

我还会通过以下方式验证您的请求是否为POST请求:

expect(req.request.method).toBe("POST");

这些是我首先想到的事情。

答案 2 :(得分:0)

我尝试了角度记录方法link,它使用req.error对我有用。希望对您有所帮助。

it('should handle an error', inject([HttpClient, HttpTestingController], (http: HttpClient, httpMock: HttpTestingController) => {

    http.get<any>('http://localhost:4200/api/data').subscribe(
        response => fail('should fail with a 403 error'),
        error => {
            expect(error.status).toBe(403);
        }
    );

    // Mocking rejects with a 403 error
    let mockRequest = httpTestingController.expectOne(req =>  
                        req.url === 'http://localhost:4200/api/data');
    let error = new ErrorEvent('ERROR');
    mockRequest.error(error, { status: 403 ,statusText: 'Invalid access.'});

    mockHttp.verify();
}));