Angular5 / ng test ERROR : TypeError: this.handler.handle is not a function

angular, testing

This is my Angular configuration :

Angular CLI: 1.7.2Node: 6.10.0OS: win32 x64Angular: 5.2.5... animations, common, compiler, compiler-cli, core, forms... language-service, platform-browser, platform-browser-dynamic... [email protected]/cli: [email protected]/build-optimizer: [email protected]/core: [email protected]/schematics: [email protected]/json-schema: [email protected]/webpack: [email protected]/angular: [email protected]/package-update: 0.3.2typescript: 2.6.2webpack: 3.11.0

My package.json file :

{  "name": "xxxx",  "version": "0.0.0",  "license": "MIT",  "scripts": {    "ng": "ng",    "start": "ng serve --proxy-config proxy.conf.json",    "build": "ng build --prod",    "test": "ng test",    "lint": "ng lint",    "e2e": "ng e2e",    "ng2ninja": "ng2ninja"  },  "private": true,  "dependencies": {    "@angular/animations": "5.2.5",    "@angular/common": "5.2.5",    "@angular/compiler": "5.2.5",    "@angular/core": "5.2.5",    "@angular/forms": "5.2.5",    "@angular/platform-browser": "5.2.5",    "@angular/platform-browser-dynamic": "5.2.5",    "@angular/router": "5.2.5",    "@ng-bootstrap/ng-bootstrap": "^1.0.0",    "bootstrap": "4.0.0",    "core-js": "2.4.1",    "font-awesome": "4.7.0",    "rxjs": "5.5.6",    "tslint-sonarts": "^1.6.0",    "yarn": "^1.5.1",    "zone.js": "0.8.19"  },  "devDependencies": {    "@angular/cli": "^1.7.1",    "@angular/compiler-cli": "5.2.5",    "@angular/language-service": "5.2.5",    "@types/jasmine": "2.8.6",    "@types/jasminewd2": "2.0.3",    "@types/node": "8.5.2",    "@ng-bootstrap/ng-bootstrap": "1.0.0",    "angular-ide": "^0.9.39",    "codelyzer": "4.1.0",    "jasmine-core": "2.8.0",    "jasmine-spec-reporter": "4.2.1",    "karma": "2.0.0",    "karma-chrome-launcher": "2.2.0",    "karma-coverage-istanbul-reporter": "1.3.3",    "karma-firefox-launcher": "1.1.0",    "karma-jasmine": "1.1.1",    "karma-jasmine-html-reporter": "0.2.2",    "karma-json-reporter": "1.2.1",    "ng2ninja": "1.0.17",    "protractor": "5.2.2",    "ts-node": "4.1.0",    "tslint": "5.9.1",    "typescript": "2.6.2"  }}

I obtain this error message when i run the command 'ng test' :

 TypeError: this.handler.handle is not a function            at [as project] node_modules/@angular/common/esm2015/http.js:1174:28)            at MergeMapSubscriber._tryNext node_modules/rxjs/_esm2015/operators/mergeMap.js:109:1)            at MergeMapSubscriber._next node_modules/rxjs/_esm2015/operators/mergeMap.js:99:1)            at node_modules/rxjs/_esm2015/Subscriber.js:83:1)            at ScalarObservable._subscribe node_modules/rxjs/_esm2015/observable/ScalarObservable.js:42:1)            at ScalarObservable._trySubscribe node_modules/rxjs/_esm2015/Observable.js:171:1)            at ScalarObservable.subscribe node_modules/rxjs/_esm2015/Observable.js:159:1)            at node_modules/rxjs/_esm2015/operators/mergeMap.js:78:1)            at Observable.subscribe node_modules/rxjs/_esm2015/Observable.js:156:1)

This is my test:

import {TestBed, inject} from '@angular/core/testing';import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing';import {UserService} from './user.service';import {environment} from '../environments/environment';import {JwtInterceptorService} from './jwt-interceptor.service';import {User} from './services/model/user';import {HttpClient, HttpHandler} from '@angular/common/http';...     it('should authenticate a user', () => {        // spy on the store method        spyOn(userService, 'storeLoggedInUser');        const credentials = {login: 'toto', password: 'titi'};        let actualUser;        userService.login(credentials).subscribe(fetchedUser => actualUser = fetchedUser);    ...      });

After analyze and debug, the problem comes from the call of the "login" method of the User Service.

Having browsed of numerous post (and solutions) i do not understand the real origin of my error message.

This is my User Service :

 login(credentials): Observable<User> {    var headers = new HttpHeaders();    headers.append('Content-Type', 'application/x-www-form-urlencoded');    var paramCredentials = "grant_type=password"      + "&credentials=true"      + "&scope=read write"      + "&accept=application/json"      + "&username=" + credentials.username      + "&password=" + credentials.password;    return<User>(`${environment.oAuthUrl}/oauth/token`, paramCredentials, {headers: headers}).pipe(      tap(user => this.storeLoggedInUser(user))    );  } storeLoggedInUser(user) {    window.localStorage.setItem('jwtToken', JSON.stringify(user));    this.jwtInterceptorService.setJwtToken(user.token);  }

Any ideas ?

Best Solution

For me, this issue came from trying to include HttpClient and HttpHandler in my providers like so:

providers: [    HttpClient,    HttpHandler]

This kept throwing errors along the lines of _TypeError: this.handle.handler is not a function

To fix this, I found I could remove HttpClient and HttpHandler from the providers and instead add HttpClientTestingModule to my imports like so:

imports: [    HttpClientTestingModule]

This solved this particular error for me in my Karma unit tests for Angular 7.