加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

如何在测试中模拟Angular 4.3 httpClient的错误响应

发布时间:2020-12-17 09:41:27 所属栏目:安全 来源:网络整理
导读:我有一个下面的拦截器auth-interceptor.service.ts import {Injectable,Injector} from '@angular/core';import {HttpErrorResponse,HttpEvent,HttpHandler,HttpInterceptor,HttpRequest} from '@angular/common/http';import {Observable} from 'rxjs/Obser
我有一个下面的拦截器auth-interceptor.service.ts
import {Injectable,Injector} from '@angular/core';
import {HttpErrorResponse,HttpEvent,HttpHandler,HttpInterceptor,HttpRequest} from '@angular/common/http';
import {Observable} from 'rxjs/Observable';
import {Cookie} from './cookie.service';
import {Router} from '@angular/router';
import {UserService} from './user.service';
import {ToasterService} from '../toaster/toaster.service';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
    constructor(private injector: Injector) {}

    private handleError(err: HttpErrorResponse): Observable<any> {
        let errorMsg;
        if (err.error instanceof Error) {
            // A client-side or network error occurred. Handle it accordingly.
            errorMsg = `An error occurred: ${err.error.message}`;
        } else {
            // The backend returned an unsuccessful response code.
            // The response body may contain clues as to what went wrong,errorMsg = `Backend returned code ${err.status},body was: ${err.error}`;
        }
        if (err.status === 401 || err.status === 403) {
            this.injector.get(UserService).purgeAuth();
            this.injector.get(ToasterService).showError(`Unauthorized`,errorMsg);
            this.injector.get(Router).navigateByUrl(`/login`);
        }
        console.error(errorMsg);
        return Observable.throw(errorMsg);
    }

    intercept(req: HttpRequest<any>,next: HttpHandler): Observable<HttpEvent<any>> {
        // Clone the request to add the new header.
        const authReq = req.clone({headers: req.headers.set(Cookie.tokenKey,Cookie.getToken())});
        // Pass on the cloned request instead of the original request.
        return next.handle(authReq).catch(err => this.handleError(err));
    }
}

现在我试图模拟http.get来抛出错误,因此方法handleError控制错误消息.

下面是我对测试用例auth-interceptor.service.specs.ts的方法

import {async,inject,TestBed} from '@angular/core/testing';

import {AuthInterceptor} from './auth-interceptor.service';
import {ApiService} from './api.service';
import {HttpClientTestingModule,HttpTestingController} from '@angular/common/http/testing';
import {environment} from '../../../environments/environment';

describe(`AuthInterceptor`,() => {
    const somePath = `/somePath`;

    beforeEach(() => {
        TestBed.configureTestingModule({
            imports: [HttpClientTestingModule],providers: [AuthInterceptor,ApiService]
        });
    });

    it(`should be created`,inject([AuthInterceptor],(service: AuthInterceptor) => {
        expect(service).toBeTruthy();
    }));


    it(`should log an error to the console on error on get()`,async(inject([ApiService,HttpTestingController],(apiService: ApiService,httpMock: HttpTestingController) => {
            spyOn(console,'error');
            apiService.get(somePath).subscribe((res) => {
                console.log(`in success:`,res);
            },(error) => {
                console.log(`in error:`,error);
            });

            const req = httpMock.expectOne(`${environment.apiUri}${somePath}`);
            req.flush({
                type: 'ERROR',status: 404,body: JSON.stringify({color: `blue`})
            });
            expect(console.error).toHaveBeenCalled();
        }))
    );
});

在刷新响应时,我不确定如何刷新错误响应,以便在我的拦截器中调用方法handleError,最终调用console.error.文档没有我的情况的任何例子.任何帮助或建议表示赞赏.

HttpTestingController类中的expectOne方法返回一个TestRequest对象.此TestRequest类具有可用于传递的flush方法

both successful and unsuccessful responses.

我们可以通过返回一个正文以及一些额外的响应头(如果有的话)来解决请求.相关信息可以在here找到.

现在,回过头来说明如何做到这一点.您可以根据您的使用情况自定义以下代码段.

http = TestBed.get(HttpTestingController);
let response:any;
let errResponse: any;
const mockErrorResponse = {
    status: 404,statusText: 'Bad Request'
};
const data = 'Invalid request parameters';
apiService.get(somePath).subscribe(res => response=res,err => errResponse=err);
http.expectOne('url/being/monitored').flush(data,mockErrorResponse);
expect(errResponse).toBe(data);

注意:在撰写此注释时,mockErrorResponse中需要statusText.相关信息可以在here找到.

P.S.:TestRequest类的错误方法可用于在我们的测试用例中模拟网络错误,因为它需要一个Error实例.以下代码段显示了这一点.

http.expectOne(someUrl).error(new ErrorEvent('network error'));

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读