gpt4 book ai didi

angular - 测试 Angular HttpInterceptor

转载 作者:行者123 更新时间:2023-12-04 12:25:51 24 4
gpt4 key购买 nike

此拦截器的目标是在服务器需要验证码 key 时重新发送请求。

但是在应该刷新 jwt token 时可以使用它。

拦截器工作正常,但我无法解释测试失败的原因。

如果响应代码 != 200,流将永远不会传递到 httpClient.get('/error').subscribe()。

这是可复制演示的链接:
https://stackblitz.com/edit/angular-testing-template-mfqwpj?embed=1&file=app/interceptor.spec.ts

import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';
import {Observable} from 'rxjs';
import {Injectable} from '@angular/core';
import {catchError, switchMap} from 'rxjs/operators';
import {CaptchaHeader, CaptchaV2Service} from 'century-lib';


@Injectable({
providedIn: 'root'
})
export class CaptchaInterceptor implements HttpInterceptor {

constructor(private captchaService: CaptchaV2Service) {
}


intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).pipe(
catchError(err => {
if (!this.captchaIsRequired(err)) {
return;
}
return this.captchaService.getCaptchaKey().pipe(
switchMap((key) => {
const newReq = this.applyCaptchaKey(req, key);
return next.handle(newReq);
})
);
})
);
}

applyCaptchaKey(req, key) {
return req.clone({
headers: req.headers.set('Captcha-Token', key)
});
}

private captchaIsRequired(error) {
return (error.status === 400 && error.headers.get('Captcha-Status') === 'required');
}

}

测试:
import {async, TestBed} from '@angular/core/testing';
import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing';
import {CaptchaV2Service} from 'century-lib';
import {HTTP_INTERCEPTORS, HttpClient, HttpHeaders} from '@angular/common/http';
import {CaptchaInterceptor} from './captcha.interceptor';
import {EventEmitter} from '@angular/core';

class MockCaptchaService {
valid = new EventEmitter<string>();
reset = new EventEmitter<boolean>();

getCaptchaKey() {
setTimeout(() => {
this.valid.emit('captcha-key');
}, 500);
return this.valid;
}
}

describe('Captcha interceptor', () => {
let httpClient: HttpClient;
let httpMock: HttpTestingController;
let interceptor: CaptchaInterceptor;

beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [
CaptchaInterceptor,
{provide: CaptchaV2Service, useValue: new MockCaptchaService()},
{provide: HTTP_INTERCEPTORS, useClass: CaptchaInterceptor, multi: true},
]
});

httpClient = TestBed.get(HttpClient);
httpMock = TestBed.get(HttpTestingController);
interceptor = TestBed.get(CaptchaInterceptor);
});


it('should construct', async(() => {
expect(interceptor).toBeDefined();
}));

it('Should interrogate the captchaService when service returns Captcha-Required', async(() => {
httpClient.get('/error').subscribe(() => {
}, () => {
});
const req = httpMock.expectOne('/error');
req.error(new ErrorEvent('Captcha Error'), {
status: 400,
statusText: 'Captcha-Error',
headers: new HttpHeaders().set('Captcha-Status', 'required')
});
expect(req.request.headers.get('Captcha-Token')).toBe('captcha-key');
httpMock.verify();
}));

afterEach(() => {
TestBed.resetTestingModule();
});


});

最佳答案

const req = httpMock.expectOne('/error');
req.error(new ErrorEvent('Captcha Error'), {
status: 400,
statusText: 'Captcha-Error',
headers: new HttpHeaders().set('Captcha-Status', 'required')
});
expect(req.request.headers.get('Captcha-Token')).toBe('captcha-key');

这没有任何意义。您有一个请求 req你用错误刷新它。这很好,但此时请求已完成,什么都不会(您有请求并得到响应)。

现在最后一行期望完全相反 - 完成的请求将以某种方式改变。

这不是您的拦截器正在做的事情。拦截器正在发出另一个请求以获取新 token (或验证验证码),然后重试原始请求。删除 expectmock.verify()将向您显示已提出的所有请求。

关于angular - 测试 Angular HttpInterceptor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52275410/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com