gpt4 book ai didi

angular - 如何对这个 Angular typescript Http Error Interceptor 进行单元测试,该拦截器从管道 observable 中捕获错误?

转载 作者:太空狗 更新时间:2023-10-29 17:49:09 27 4
gpt4 key购买 nike

我正在进行一项实验,通过测试其他人的代码(例如自动化单元和端到端测试)来学习 Angular 和 typescript 。在我对其进行测试后,我计划将其重新用于我正在为大学教室开展的宠物项目。

我至少对这里的代码进行了一半的单元测试:http://jasonwatmore.com/post/2018/05/16/angular-6-user-registration-and-login-example-tutorial

一段时间以来,我一直在尝试对以下代码进行单元测试,但到目前为止,我根据自己的想法或互联网上的想法进行的所有尝试都没有成功:

import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from "@angular/common/http";
import { AuthenticationService } from "src/app/authenticationService/AuthenticationService";
import { Observable, throwError } from "rxjs";
import { catchError } from "rxjs/operators";
import { Injectable } from "@angular/core";

@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
constructor(private authenticationService: AuthenticationService) {}

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
console.log('before error handle')
return next.handle(request).pipe(catchError(err => {

console.log('in error handle')

if (err.status === 401) {
// auto logout if 401 response returned from api
this.authenticationService.logout();
location.reload(true);
}

const error = err.error.message || err.statusText;
return throwError(error);
}))
}

}

以下测试代码和几个变体未能使“错误句柄”消息显示在控制台日志中:

import { ErrorInterceptor } from "./ErrorInterceptor";
import { of, throwError, defer } from "rxjs";

describe('ErrorInterceptor', () => {
let errorInterceptor;
let authenticationServiceSpy;

beforeEach(() => {
authenticationServiceSpy = jasmine.createSpyObj('AuthenticationService', ['logout']);
errorInterceptor = new ErrorInterceptor(authenticationServiceSpy);
})

it('should create', () => {
expect(errorInterceptor).toBeTruthy();
})

describe('intercept', () => {
let httpRequestSpy;
let httpHandlerSpy;
const error = {status: 401, statusText: 'error'};

it('should auto logout if 401 response returned from api', () => {
//arrange
httpRequestSpy = jasmine.createSpyObj('HttpRequest', ['doesNotMatter']);
httpHandlerSpy = jasmine.createSpyObj('HttpHandler', ['handle']);
httpHandlerSpy.handle.and.returnValue({
pipe: () => {
return fakeAsyncResponseWithError({});
}
});

//act
errorInterceptor.intercept(httpRequestSpy, httpHandlerSpy);

//assert
//TBD

function fakeAsyncResponseWithError<T>(data: T) {
return defer(() => throwError(error));
}
})
})
})

最佳答案

这里有几个问题。

  • 首先,您从 httpHandlerSpy.handle() 返回的值需要是一个 Observable,因为它上面已经有管道运算符,然后 HttpInterceptor 代码可以根据需要将其通过管道传递给 catchError。
  • 其次,HttpInterceptor 返回一个 Observable,要“执行”它,需要订阅它。

我整理了一个 Stackblitz来展示我将如何处理这个问题。

来自 Stackblitz,这是规范(it 函数):

it('should auto logout if 401 response returned from api', () => {
//arrange
httpRequestSpy = jasmine.createSpyObj('HttpRequest', ['doesNotMatter']);
httpHandlerSpy = jasmine.createSpyObj('HttpHandler', ['handle']);
httpHandlerSpy.handle.and.returnValue(throwError(
{error:
{message: 'test-error'}
}
));
//act
errorInterceptor.intercept(httpRequestSpy, httpHandlerSpy)
.subscribe(
result => console.log('good', result),
err => {
console.log('error', err);
expect(err).toEqual('test-error');
}
);

//assert

})

希望对您有所帮助。

关于angular - 如何对这个 Angular typescript Http Error Interceptor 进行单元测试,该拦截器从管道 observable 中捕获错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53683895/

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