1

I have a basic HttpInterceptor which appends content-type to my post requests:

import { Injectable } from '@angular/core';
import {
  HttpHandler,
  HttpInterceptor,
  HttpRequest,
} from '@angular/common/http';

@Injectable()
export class MyInterceptor implements HttpInterceptor {
  public intercept(
    request: HttpRequest<Record<string, unknown>>,
    next: HttpHandler,
  ) {
    console.log('REQUEST WAS INTERCEPTED');
    if (
      (request.method === 'POST' )
    ) {
      request = request.clone({
        setHeaders: {
          'Content-Type': 'application/json;charset=UTF-8',
        },
      });
    }

    return next.handle(request);
  }
}

Here is the test:

import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { TestBed } from '@angular/core/testing';

import { Data } from '@angular/router';
import { HttpClient, HTTP_INTERCEPTORS } from '@angular/common/http';
import { MyInterceptor } from './my-interceptor.service';

const testData: Data[] = [{ name: 'bob' }, { name: 'alice' }];

describe('PROVIDE_CONTENT_TYPE_HTTP_INTERCEPTOR', () => {
  let http: HttpClient;
  let httpTestingController: HttpTestingController;

  beforeEach(async () => {
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule],
      providers: [{provide: HTTP_INTERCEPTORS,
        useClass: MyInterceptor,
        multi: true,}]
    });

    http = TestBed.inject(HttpClient);
    httpTestingController = TestBed.inject(HttpTestingController);
  });

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

  it('handles POST requests', (done) => {
    http.post('/data', {}).subscribe((data: any) => {
      console.log('POST REQUEST HAS FIRED - NEVER HAPPENS');
      expect(data).toEqual(testData);
      done();
    });
    const request = httpTestingController.expectOne('/data');
    request.flush(testData);
  });

  it('ignores GET requests', (done) => {
    http.get('/data').subscribe((data: any) => {
      console.log('GET REQUEST HAS FIRED - SUCCESS');
      expect(data).toEqual(testData);
      done();
    });
    const request = httpTestingController.expectOne('/data');
    request.flush(testData);
  });
});

While GET request is fired, POST request never happens so that the first test fails with "Expected one matching request for criteria "Match URL: /data", found none.".

To me it does not look like some async issue - no request is logged from the intercepter itself.

Tested in Angular 12 and 13 (Node 14.17), without success. It used to work in Angular 11. I wonder if the implementation of HttpTestingModule changed? Why does GET request is sent while POST not?

I tried to use a wrapper service around HttpClient, it does not work neither.

Here is the minimal reproducible code on GitHub

Maria K.
  • 219
  • 1
  • 8
  • The interception itself works, it is just that the test of the http-request doesn't work? – fonzane Aug 25 '22 at 15:16
  • Yes, only the test fails – Maria K. Aug 25 '22 at 15:26
  • I've added another example with a simple ApiService+test to the GitHub project. Looks like a weird Angular-Node combination bug to me. I don't even know if you can reproduce it. – Maria K. Aug 25 '22 at 15:35
  • Which version of Jest, jest-preset-angular, ts-jest, ts-node, and TypeScript? Which Angular test builder? Which CLI? What do your Jest configurations and presets look like? – Lars Gyrup Brink Nielsen Aug 26 '22 at 05:19
  • you can look all of that up in the package.json – fonzane Aug 26 '22 at 10:21
  • 1
    @LarsGyrupBrinkNielsen thanks for the hint. Indeed it was a node version and Angular version mismatch. If you post your comment as an answer, I'm glad to accept it. – Maria K. Jan 10 '23 at 19:22

2 Answers2

1

setHeaders in clone() looks to have been deprecated in 14:

https://angular.io/api/common/http/HttpRequest

compare to:

https://v12.angular.io/api/common/http/HttpRequest

mbojko
  • 13,503
  • 1
  • 16
  • 26
  • Hi, in my case I test with Angular 12 and 13, so the deprecation is not yet relevant for me. Moreover, the request is not fired at all... – Maria K. Aug 25 '22 at 15:13
0

As a first step when troubleshooting strange situations like this, make sure the versions of the following dependencies are compatible:

  • jest
  • jest-preset-angular
  • ts-jest
  • ts-node
  • typescript
  • @angular/cli
  • @angular/core
  • The Angular builder used by your test target, for example @angular-devkit/build-angular for Karma + Angular CLI, @nrwl/jest:jest for Jest + Nx, or @angular-builders/jest for Jest + Angular CLI
  • Node.js

For Node.js, TypeScript, Angular CLI, and Angular Core compatibility refer to this compatibility matrix.

Then review your Jest configurations and presets.

Lars Gyrup Brink Nielsen
  • 3,939
  • 2
  • 34
  • 35