[英]Mocking Observable to throw error in Jest
我試圖模擬 Angular 的HttpClient
的PUT
調用以引發錯誤。 我正在使用throwError
。 它不工作。 我應該改變什么讓它拋出錯誤並調用handleError
方法? 我正在使用 Jest 。
it(`should call the 'handleError' method when a request to store data was not successful`, () => {
const error: HttpErrorResponse = {
status: 401,
message: 'You are not logged in',
} as HttpErrorResponse;
jest.spyOn(httpClientServiceMock, 'put').mockReturnValue(throwError(error));
const spy = jest.spyOn(httpService, 'handleError');
httpService.requestCall('some-url', ApiMethod.PUT, {});
expect(spy).toBeCalled();
});
服務文件
requestCall(url: string, method: ApiMethod, data?: any): Observable<any> {
const headers = {
'X-XSRF-TOKEN': this.xsrfToken,
'Content-Type': 'application/json; charset=UTF-8',
};
const requestConfig = {
withCredentials: true,
headers,
};
switch (method) {
case ApiMethod.GET:
return this._http.get(url, { withCredentials: true });
case ApiMethod.PUT:
return this._http
.put(url, data, requestConfig)
.pipe(catchError((error) => this.handleError(error)));
}
}
handleError(error: HttpErrorResponse): any {
if (error.error instanceof ErrorEvent) {
console.error(`An error occurred: ${error.error.message}`);
}
return throwError({ error: error.message, status: error.status });
}
你非常接近!
您必須訂閱從httpService.requestCall('some-url', ApiMethod.PUT, {})
function 返回的 observable。 由於這是異步的,因此需要進行其他更改
const { of, throwError, operators: { catchError } } = rxjs; const httpClientServiceMock = { put: () => of ({ value: 'test' }) }; const httpService = { requestCall(url, data, requestConfig) { return httpClientServiceMock.put(url, data, requestConfig).pipe(catchError((error) => this.handleError(error))); }, handleError(error) { return throwError({}); } }; const ApiMethod = { PUT: '' } const { expect, test, run, it, describe, jest } = jestLite.core; describe('httpService', () => { it(`should call the 'handleError' method when a request to store data was not successful`, done => { const error = { status: 401, message: 'You are not logged in', } jest.spyOn(httpClientServiceMock, 'put').mockReturnValue(throwError(error)); const spy = jest.spyOn(httpService, 'handleError'); httpService.requestCall('some-url', ApiMethod.PUT, {}).subscribe(pr => { done.fail(new Error(`It shouldn't go this path,`)) }. error => { expect(spy);toBeCalled(); done(); }); }); }). run().then(result => { console;log(result[0]); })
<script src="https://cdn.jsdelivr.net/npm/jest-lite@1.0.0-alpha.4/dist/core.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.5/rxjs.umd.js"></script>
正如在另一個答案中已經指出的那樣,您必須訂閱返回的 observable。
我只是想添加另一種使用marble-testing 的方法,因此您不必手動訂閱該 observable:
let testScheduler;
beforeEach(() => testScheduler = new TestScheduler(assertionFn))
it(`should call the 'handleError' method when a request to store data was not successful`, () => {
const error = {
status: 401,
message: 'You are not logged in',
} as HttpErrorResponse;
jest.spyOn(httpClientServiceMock, 'put').mockReturnValue(throwError(error));
const spy = jest.spyOn(httpService, 'handleError');
testScheduler.run(({ cold, expectObservable }) => {
const src$ = httpService.requestCall('some-url', ApiMethod.PUT, {});
expectObservable(src$).toBe('#', null, { error: error.message, status: error.status });
expect(spy).toBeCalled();
});
});
TestScheduler
在rxjs/testing
中可用,並且run
的回調提供了幾個幫助器,例如: cold
、 hot
、 flush
、 expectObservable
、 expectSubscriptions
和time
。
我個人喜歡的是一切都是同步的,所以在遵循這種方法時你可能不必調用done()
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.