Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/32.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 10:使用HttpInterceptor进行单元测试,修改响应而不获取HttpResponse_Angular_Unit Testing_Karma Jasmine_Angular Http Interceptors_Angular Test - Fatal编程技术网

Angular 10:使用HttpInterceptor进行单元测试,修改响应而不获取HttpResponse

Angular 10:使用HttpInterceptor进行单元测试,修改响应而不获取HttpResponse,angular,unit-testing,karma-jasmine,angular-http-interceptors,angular-test,Angular,Unit Testing,Karma Jasmine,Angular Http Interceptors,Angular Test,如果到处搜索答案,到目前为止,我尝试过的每件事都会产生相同的缺失信息 这是运行Angular 10的最新版本的Karma/Jasmine 本质上,我有一个HTTP拦截器,它查看返回对象的内容类型。如果是json,继续正常操作,如果是html…然后抛出一个错误 import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/

如果到处搜索答案,到目前为止,我尝试过的每件事都会产生相同的缺失信息

这是运行Angular 10的最新版本的Karma/Jasmine

本质上,我有一个HTTP拦截器,它查看返回对象的内容类型。如果是json,继续正常操作,如果是html…然后抛出一个错误

import {
    HttpEvent,
    HttpHandler,
    HttpInterceptor,
    HttpRequest,
    HttpResponse
} from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { httpStatusCodes } from '../../../shared/enums/httpStatusCodes.enum';
import { errorResponse } from './../../../shared/models/errorResponse.model';

@Injectable()
export class WafErrorInterceptor implements HttpInterceptor {
    intercept(
        request: HttpRequest<any>,
        next: HttpHandler
    ): Observable<HttpEvent<any>> {
        return next.handle(request).pipe(
            map((event: HttpEvent<any>) => {
                console.log(event instanceof HttpResponse);
                if (
                    event instanceof HttpResponse &&
                    event.headers.has('content-type') &&
                    event.headers.get('content-type') === 'application/json'
                ) {
                    return event;
                }

                const throwErrorResponse = new errorResponse(
                    httpStatusCodes.WAF_ERROR,
                    '99999',
                    event instanceof HttpResponse
                        ? event.body
                        : 'unknown error occurred'
                );
                throw throwErrorResponse;
            })
        );
    }
}
导入{
HttpEvent,
HttpHandler,
HttpInterceptor,
HttpRequest,
HttpResponse
}来自“@angular/common/http”;
从“@angular/core”导入{Injectable};
从“rxjs”导入{Observable};
从“rxjs/operators”导入{map};
从“../../../shared/enums/httpStatusCodes.enum”导入{httpStatusCodes};
从“../../../../shared/models/errorResponse.model”导入{errorResponse};
@可注射()
导出类WafErrorInterceptor实现HttpInterceptor{
拦截(
请求:HttpRequest,
下一步:HttpHandler
):可见{
返回next.handle(request.pipe)(
映射((事件:HttpEvent)=>{
log(HttpResponse的事件实例);
如果(
HttpResponse的事件实例&&
event.headers.has('content-type')&&
event.headers.get('content-type')='application/json'
) {
返回事件;
}
const-throwErrorResponse=新的错误响应(
httpStatusCodes.WAF_错误,
'99999',
HttpResponse的事件实例
?事件主体
:“发生未知错误”
);
投掷反应;
})
);
}
}
然后在我的单元测试中,我运行以下命令:

import {
    HttpClient,
    HttpHeaders,
    HttpResponse,
    HTTP_INTERCEPTORS
} from '@angular/common/http';
import {
    HttpClientTestingModule,
    HttpTestingController
} from '@angular/common/http/testing';
import { fakeAsync, TestBed, tick } from '@angular/core/testing';
import { errorResponse } from './../../../shared/models/errorResponse.model';
import { WafErrorInterceptor } from './waf-error.service';

describe('WafErrorInterceptor', () => {
    let httpMock: HttpTestingController;
    let httpClient: HttpClient;

    beforeEach(() => {
        TestBed.configureTestingModule({
            imports: [HttpClientTestingModule],
            providers: [
                {
                    provide: HTTP_INTERCEPTORS,
                    useClass: WafErrorInterceptor,
                    multi: true
                }
            ]
        });
        httpMock = TestBed.get(HttpTestingController);
        httpClient = TestBed.get(HttpClient);
    });

    afterEach(() => {
        httpMock.verify();
    });

    it('intercept: when no error, then subscribe returns successfully', () => {
        const testData: string = 'test';

        httpClient.get<string>('https://secure.testurl.com/success').subscribe(
            (data) => expect(data).toBeTruthy(),
            (error: errorResponse) => {
                console.log(error);
                fail('error should not have been called');
            }
        );
        tick();
        let req = httpMock.expectOne('https://secure.testurl.com/success');
        tick();

        let httpHeaders = new HttpHeaders();
        httpHeaders.set('content-type', 'application/json');

        const expectedResponse = new HttpResponse<string>({
            status: 200,
            statusText: 'OK',
            body: testData,
            headers: httpHeaders
        });

        //req.flush(expectedResponse);
        req.event(expectedResponse);
    });
});
导入{
HttpClient,
HttpHeader,
HttpResponse,
HTTP_拦截器
}来自“@angular/common/http”;
进口{
HttpClientTestingModule,
HttpTestingController
}来自“@angular/common/http/testing”;
从'@angular/core/testing'导入{fakeAsync,TestBed,tick};
从“../../../../shared/models/errorResponse.model”导入{errorResponse};
从“./waf error.service”导入{WafErrorInterceptor};
描述('WafErrorInterceptor',()=>{
让httpock:HttpTestingController;
let-httpClient:httpClient;
在每个之前(()=>{
TestBed.configureTestingModule({
导入:[HttpClientTestingModule],
供应商:[
{
提供:HTTP_拦截器,
useClass:WafErrorInterceptor,
多:真的
}
]
});
httpMock=TestBed.get(HttpTestingController);
httpClient=TestBed.get(httpClient);
});
之后(()=>{
httpMock.verify();
});
它('截取:当没有错误时,订阅成功返回',()=>{
常量testData:string='test';
httpClient.get('https://secure.testurl.com/success)。订阅(
(数据)=>expect(数据).toBeTruthy(),
(错误:errorResponse)=>{
console.log(错误);
失败(“不应调用错误”);
}
);
勾选();
let req=httpMock.expectOne('https://secure.testurl.com/success');
勾选();
设httpHeaders=newHttpHeaders();
httpHeaders.set('content-type','application/json');
const expectedResponse=新的HttpResponse({
现状:200,
statusText:'确定',
正文:testData,
标题:httpHeaders
});
//要求冲洗(预期响应);
请求事件(预期响应);
});
});
我已经尝试过刷新,在这里我只发送回数据,在那里我发送回数据和标题/状态。我发回一个httpresponse,等等。每次,当它进入拦截器时,拦截器不会看到httpresponse类型的响应,并且console.log总是返回false

我甚至刚刚创建了一个单元测试,单元测试在其中发送一个模拟对象…甚至还有同样的问题

想法

更新: 下面的答案适用于Map,但在测试catchErrorInterceptor时仍然存在问题。代码在我的站点上运行。我们的API返回一个对象,其中错误包含一个错误数组。因此,我们抓住第一个并使用它

@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
    intercept(
        request: HttpRequest<any>,
        next: HttpHandler
    ): Observable<HttpEvent<any>> {
        return next.handle(request).pipe(
            catchError((error: HttpErrorResponse) => {
                let statusCode = httpStatusCodes.CONFLICT;
                let errorMessage = '';
                let errorCode = '99999';

                statusCode =
                    error.status === 0
                        ? httpStatusCodes.INTERNAL_SERVER_ERROR
                        : error.status;

                if (error.error.errors && error.error.errors.length > 0) {
                    errorCode = error.error.errors[0].code;
                    errorMessage = error.error.errors[0].description;
                } else {
                    errorMessage = error.message;
                }

                const throwErrorResponse = new errorResponse(
                    statusCode,
                    errorCode,
                    errorMessage
                );

                return throwError(throwErrorResponse);
            })
        );
    }
}
@Injectable()
导出类ErrorInterceptor实现HttpInterceptor{
拦截(
请求:HttpRequest,
下一步:HttpHandler
):可见{
返回next.handle(request.pipe)(
catchError((错误:HttpErrorResponse)=>{
让statusCode=httpStatusCodes.CONFLICT;
让errorMessage='';
让errorCode='99999';
状态码=
错误。状态===0
?httpStatusCodes.INTERNAL\u服务器\u错误
:错误。状态;
if(error.error.errors&&error.error.errors.length>0){
errorCode=错误。错误。错误[0]。代码;
errorMessage=错误。错误。错误[0]。说明;
}否则{
errorMessage=error.message;
}
const-throwErrorResponse=新的错误响应(
状态码,
错误代码,
错误信息
);
返回投掷者(投掷者反应);
})
);
}
}
以下是其中一项测试:

    it('intercept: when delibarate 409, then error returned', (done) => {
        httpClient
            .get<string>('https://secure.go2bank.com/error')
            .pipe(skip(1))
            .subscribe(
                (data) => fail('should have failed with the 404 error'),
                (error: errorResponse) => {
                    expect(error).toBeTruthy(); // check if executed
                    expect(error.httpStatusCodes).toBe(
                        httpStatusCodes.CONFLICT
                    );
                    expect(error.errorCode).toBe('1007');
                    expect(error.errorMessage).toBe(
                        'Validation error Authorization'
                    );
                    done();
                }
            );

        const errorInitEvent: ErrorEventInit = {
            message: null,
            error: {
                errors: [
                    {
                        code: '1007',
                        description: 'Validation error Authorization.',
                        message: null,
                        link: null,
                        additionalinfo: null
                    }
                ]
            }),
            lineno: null,
            colno: null,
            filename: null
        };

        let error = new ErrorEvent('ERROR', errorInitEvent);

        httpMock.expectOne('https://secure.go2bank.com/error').error(error, {
            status: httpStatusCodes.CONFLICT,
            statusText: 'Conflict',
            headers: new HttpHeaders().set('content-type', 'application/json')
        });
    });
it('intercept:when delibarate 409,然后返回错误',(done)=>{
httpClient
.get('https://secure.go2bank.com/error')
.管道(箕斗(1))
.订阅(
(数据)=>fail('404错误本应失败'),
(错误:errorResponse)=>{
import {
  HttpEventType,
  ...
} from '@angular/common/http';
...

map((event: HttpEvent<any>) => {
  if (event.type === HttpEventType.Sent) { <---------- add this
    return event;
  }
  
  if (
    event instanceof HttpResponse &&
    event.headers.has('content-type') &&
    event.headers.get('content-type') === 'application/json'
  ) {
    return event;
  }
  ...
flush(body, opts?: {
    headers?: HttpHeaders | {
        [name: string]: string | string[];
    };
    status?: number;
    statusText?: string;
})
it('intercept: when no error, then subscribe returns successfully', () => {
  const testData: string = 'test';

  httpClient.get<string>('https://secure.testurl.com/success').subscribe(
    (data) => expect(data).toBeTruthy(),
    (error: errorResponse) => {
      console.log(error);
      fail('error should not have been called');
    }
  );

  const req = httpMock.expectOne('https://secure.testurl.com/success');

  req.flush(testData, {
    status: 200,
    statusText: 'OK',
    headers: new HttpHeaders().set('content-type', 'application/json')
  });
});