Having trouble implementing catchError in a unit test for an HttpInterceptor in Angular 11

I am facing challenges in completing a unit test for my HttpInterceptor. The interceptor serves as a global error handler and is set to trigger on catchError(httpResponseError). While the interceptor functions perfectly fine on my website, I am struggling to create a successful unit test for the code.

Below is the code snippet for the Interceptor:

import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, throwError } from 'rxjs';
import { retry, tap, catchError } from 'rxjs/operators';
import { HttpServiceError } from '../models/httpServiceError.model';
import { LoggingService, LogLevel } from '../services/logging.service';

@Injectable({
    providedIn: 'root'
})

export class HttpResponseInterceptorService implements HttpInterceptor{
  public logLevel!: LogLevel;

  constructor(private readonly loggingService: LoggingService) { 
// Intentionally left blank    
  }

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(request)
      .pipe(
        retry(1),
        tap(() => console.log('ResponseInterceptor called')),
        catchError((error:HttpErrorResponse) => {          
          console.log('HttpErrorResponse caught')
          this.handleHttpError(error);
          return throwError(error);
        }))
  }

  // Additional code for handling errors and logging messages

In my testing environment, only the first `console.log` statement actually gets triggered instead of the expected behavior.

Furthermore, here's an excerpt from my spec file:

import { HttpClient, HttpErrorResponse, HttpEvent, HttpHandler, HttpRequest, HttpResponse, HTTP_INTERCEPTORS } from '@angular/common/http';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { fakeAsync, inject, TestBed } from '@angular/core/testing';
import { of } from 'rxjs';
import { take } from 'rxjs/operators';
import { LoggingService } from '../services/logging.service';

import { HttpResponseInterceptorService } from './httpresponseinterceptor.service';

describe('HttpResponseInterceptorService', () => {
  let interceptor: HttpResponseInterceptorService;  
  let httpMock: HttpTestingController;
  let loggingService: LoggingService;
  let httpClient: HttpClient;

  beforeEach(() => {
    // TestBed configuration and injection setup
  });

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

  // Detailed unit test cases with specific expectations
  

The tests involving triggering error responses have not been successful so far. All ideas and suggestions are greatly appreciated!

Thank you, Bjarne

Answer №1

It seems like the issue lies with the 'retry(1)' function in your code. If you want to successfully handle errors using the catchError method, you need to make sure that you call numberOfRetry + 1 times for your API.

You could potentially resolve this by attempting the following approach:

    let req = httpMock.expectOne("/api");
    req.error(new ErrorEvent('404 First Error'), errorResponse);
    req = httpMock.expectOne("/api");
    req.error(new ErrorEvent('404 Second Error'), errorResponse);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Explore one of the elements within a tuple

Can we simplify mapping a tuple element in TypeScript? I'm seeking an elegant way to abstract the following task const arr: [string, string][] = [['a', 'b'], ['c', 'd'], ['e', 'f']] const f ...

classes_1.Individual is not a callable

I am facing some difficulties with imports and exports in my self-made TypeScript project. Within the "classes" folder, I have individual files for each class that export them. To simplify usage in code, I created an "index.ts" file that imports all class ...

The issue of SVG not displaying on Chrome has been observed in Angular 6

I am working on loading multiple widgets in Angular 6. I have created a loading symbol using SVG, and I am using the following logic to hide and show the loading div until all widgets are loaded. Interestingly, in Firefox, the loading SVG appears as expect ...

Tips for retrieving the return value from a function with an error handling callback

I am having an issue with my function that is supposed to return data or throw an error from a JSON web token custom function. The problem I am facing is that the data returned from the signer part of the function is not being assigned to the token const a ...

Unable to locate the module styled-components/native in React Native

When adding types in tsconfig.json to remove TypeScript complaints and enable navigation to a package, the code looks like this: import styled, {ThemeProvider} from 'styled-components/native'; The package needed is: @types/styled-components-re ...

In what ways can one determine the function parameter of a union type?

I am working with a union type of functions: function Function1(arg0: string, arg1: any[], name: "hello" | "bye") { return name; } function Function2(arg0: string, arg1: any[], name: "foo" | "bar") { return name ...

A single element containing two duplicates of identical services

I am encountering an issue with my query builder service in a component where I need to use it twice. Despite trying to inject the service twice, it seems that they just reference each other instead of functioning independently, as shown below: @Component( ...

Running Protractor tests with 'directConnect: true' causes the ERROR:browser_switcher_service.cc(238)] XXX Init() to be thrown

While running Protractor tests with directConnect: true, I am encountering an error as soon as the browser window appears. Interestingly, the test continues to run smoothly without any apparent issues. However, when I switch to Firefox or use seleniumAddr ...

Filter through the array of objects using the title key

I'm attempting to extract specific data by filtering the 'page_title' key. Below is a snippet of my JSON object: { "page_components": [ { "page_title": "My Account", "row_block": [ { "heading": "", "sub_headi ...

Ways to retrieve "this" while utilizing a service for handling HTTP response errors

I have a basic notification system in place: @Injectable({ providedIn: 'root', }) export class NotificationService { constructor(private snackBar: MatSnackBar) {} public showNotification(message: string, style: string = 'success' ...

I can't find my unit test in the Test Explorer

I'm currently working on configuring a unit test in Typescript using tsUnit. To ensure that everything is set up correctly, I've created a simple test. However, whenever I try to run all tests in Test Explorer, no results are displayed! It appear ...

Using React and Typescript, implement an Ant Design Table that includes a Dropdown column. This column should pass

Next Row: { title: "Adventure", render: (item: ToDoItem) => { //<- this item return ( <Dropdown overlay={menu}> <Button> Explore <DownOutlined /> </Button> </Dropdown&g ...

Restricting a Blob to a particular data type

As seen in the GitHub link, the definition of Blob is specified: /** A file-like object of immutable, raw data. Blobs represent data that isn't necessarily in a JavaScript-native format. The File interface is based on Blob, inheriting blob functional ...

Tips for utilizing withNavigation from react-navigation in a TypeScript environment

Currently, I am working on building an app using react-native, react-navigation, and typescript. The app consists of only two screens - HomeScreen and ConfigScreen, along with one component named GoToConfigButton. Here is the code for both screens: HomeSc ...

IntelliJ IDEA does not support the recognition of HTML tags and directives

I seem to have lost the ability to switch between my HTML and TS files in Intellij IDEA; the tags, directives, and autocompletion in HTML are no longer working. Additionally, I'm receiving some warnings: https://i.stack.imgur.com/QjmNk.png Is there ...

Iterate through each item in an object using Angular

I attempted to utilize a forEach loop, but it's indicating that it's undefined for some reason. Here is my code snippet: var array: MoneyDTO[] = prices array.forEach(function (money: MoneyDTO) { if (money.currency == 'QTW& ...

Searching for client using mqtt.js in Angular2 with Typescript yields no results

I am facing a unique issue while trying to incorporate the mqtt.js library into Angular 2 using TypeScript. Below is my app.component.ts file: import { Component } from '@angular/core'; import * as mqtt from 'mqtt'; @Component({ sel ...

The random number generator in TypeScript not functioning as expected

I have a simple question that I can't seem to find the answer to because I struggle with math. I have a formula for generating a random number. numRandomed: any; constructor(public navCtrl: NavController, public navParams: NavParams) { } p ...

Simplifying parameter types for error handling in app.use callback with Express.js and TypeScript

With some familiarity with TypeScript but a newcomer to Express.js, I aim to develop a generic error handler for my Express.js app built in TypeScript. The code snippet below is functional in JavaScript: // catch 404 and forward to error handler app.use((r ...

Is there a way to obtain asynchronous stack traces using Node.js and TypeScript?

When working with TypeScript, I encountered an issue with stack traces. It seems that only the bottommost function name is displayed. My setup includes Node.js v12.4.0 on Windows 10 (1803). Below is the code snippet: async function thrower() { throw new ...