javascript - Angular 6 服务无法通过单元测试(NullInjectorError : No provider for HttpClient!)

标签 javascript angular typescript unit-testing angular6

当我运行 `ng test' 时,我正在尝试在 angular 6 中进行单元测试

出现以下错误

Error: StaticInjectorError(DynamicTestModule)[HttpClient]:
          StaticInjectorError(Platform: core)[HttpClient]:
            NullInjectorError: No provider for HttpClient!
            at NullInjector.push../node_modules/@angular/core/fesm5/core.js.NullInjector.get (http://localhost:9876/node_modules/@angular/core/fesm5/core.js?:691:1)
            at resolveToken (http://localhost:9876/node_modules/@angular/core/fesm5/core.js?:928:1)
            at tryResolveToken (http://localhost:9876/node_modules/@angular/core/fesm5/core.js?:872:1)
            at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (http://localhost:9876/node_modules/@angular/core/fesm5/core.js?:769:1)
            at resolveToken (http://localhost:9876/node_modules/@angular/core/fesm5/core.js?:928:1)
            at tryResolveToken (http://localhost:9876/node_modules/@angular/core/fesm5/core.js?:872:1)
            at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (http://localhost:9876/node_modules/@angular/core/fesm5/core.js?:769:1)
            at resolveNgModuleDep (http://localhost:9876/node_modules/@angular/core/fesm5/core.js?:17435:1)
            at NgModuleRef_.push../node_modules/@angular/core/fesm5/core.js.NgModuleRef_.get (http://localhost:9876/node_modules/@angular/core/fesm5/core.js?:18124:1)
            at inject (http://localhost:9876/node_modules/@angular/core/fesm5/core.js?:1023:1)
Chrome 69.0.3497 (Windows 10 0.0.0): Executed 2 of 12 (2 FAILED) (0 secs / 0.119 secs)
Chrome 69.0.3497 (Windows 10 0.0.0) UserService should have add function FAILED
        Error: StaticInjectorError(DynamicTestModule)[HttpClient]:
          StaticInjectorError(Platform: core)[HttpClient]:
            NullInjectorError: No provider for HttpClient!
            at NullInjector.push../node_modules/@angular/core/fesm5/core.js.NullInjector.get (http://localhost:9876/node_modules/@angular/core/fesm5/core.js?:691:1)
            at resolveToken (http://localhost:9876/node_modules/@angular/core/fesm5/core.js?:928:1)
            at tryResolveToken (http://localhost:9876/node_modules/@angular/core/fesm5/core.js?:872:1)
            at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (http://localhost:9876/node_modules/@angular/core/fesm5/core.js?:769:1)
            at resolveToken (http://localhost:9876/node_modules/@angular/core/fesm5/core.js?:928:1)
            at tryResolveToken (http://localhost:9876/node_modules/@angular/core/fesm5/core.js?:872:1)
            at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (http://localhost:9876/node_modules/@angular/core/fesm5/core.js?:769:1)
            at resolveNgModuleDep (http://localhost:9876/node_modules/@angular/core/fesm5/core.js?:17435:1)
            at NgModuleRef_.push../node_modules/@angular/core/fesm5/core.js.NgModuleRef_.get (http://localhost:9876/node_modules/@angular/core/fesm5/core.js?:18124:1)
Chrome 69.0.3497 (Windows 10 0.0.0): Executed 2 of 12 (2 FAILED) (skipped 10) ERROR (0.094 secs / 0.119 secs)

这是服务规范文件

 import { TestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import {HttpClientModule} from '@angular/common/http';
import { UserService } from './user.service';

TestBed.configureTestingModule({
    imports: [HttpClientTestingModule, HttpClientModule],
    providers: [UserService]
});

fdescribe('UserService', () => {
  beforeEach(() => TestBed.configureTestingModule({}));

  it('should be created', () => {
    const service: UserService = TestBed.get(UserService);
    expect(service).toBeTruthy();
  });

  it('should have add function', () => {
    const service: UserService = TestBed.get(UserService);
    expect(service.addComments).toBeTruthy();
  });

});

她是usersevice的ts文件

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import {Status } from '../model/statuses.model';
import { Comment } from '../model/comments.model';
import { User } from '../model/user.model';
import { Headers, Http, Response } from '@angular/http';
import { catchError, tap, map } from 'rxjs/operators';
import { Observable, of, throwError } from 'rxjs';
import { HttpHeaders, HttpErrorResponse } from '@angular/common/http';

const httpOptions = {
  headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};

@Injectable({
  providedIn: 'root'
})
export class UserService {
  status: Status[];
  constructor(private http: HttpClient) { }
  statusUrl = 'http://localhost:3000/statuses';
  commentsUrl = 'http://localhost:3000/comment';
  usersUrl = 'http://localhost:3000/users';

  private extractData(res: Response) {
    // tslint:disable-next-line:prefer-const
    let body = res;
    return body || {};
  }

 // get all users
  getUsers(): Observable<any> {
    return this.http.get(this.usersUrl).pipe(
      map(this.extractData),
      catchError(this.handleError));
    }

  // get users by ID
  getUserById(id: number) {
    return this.http.get<User>(this.usersUrl + '/' + id);
  }

  // get all statuses
  getStatuses(): Observable<any> {
    return this.http.get(this.statusUrl).pipe(
      map(this.extractData),
      catchError(this.handleError));
    }

  // add comments
  addComments(comments: Comment) {
    comments.localTime = new Date();
    return this.http.post(this.commentsUrl, comments);
  }

  // get comments
  getComments(id: number): Observable<any> {
    return this.http.get(this.commentsUrl).pipe(
      map(this.extractData),
      catchError(this.handleError));
  }
  // upadet user status
  updateStatus(status: Status) {
  return this.http.put(this.statusUrl + '/' + status.id, status);
  }

  // add user status
  addStatus(status: Status) {
    return this.http.put(this.statusUrl, status);
   }
   // Errors Handler
  private handleError(error: HttpErrorResponse) {
    if (error.error instanceof ErrorEvent) {
      // A client-side or network error occurred. Handle it accordingly.
      console.error('An error occurred:', error.error.message);
    } else {
      // The backend returned an unsuccessful response code.
      // The response body may contain clues as to what went wrong,
      console.error(
        `Backend returned code ${error.status}, ` +
        `body was: ${error.error}`);
    }
    // return an observable with a user-facing error message
    return throwError('Something bad happened; please try again later.');
  }

}

我尝试了来自 stack oveflow 的不同解决方案,但没有任何效果,我什至在这里尝试了这个解决方案 unit test errors angular 5

但不幸的是,在 angular 6 中没有任何效果

我做错了什么,我们将不胜感激????

最佳答案

我相信你的问题依赖于你正在做两次的 TestBed 定义,可能这就是问题所在:

 //first testbed definition, move this into the beforeEach
TestBed.configureTestingModule({
  imports: [HttpClientTestingModule, HttpClientModule],
  providers: [UserService]
});

describe('UserService', () => {
  beforeEach(() => TestBed.configureTestingModule({})); <- second one, cleanning the module definition before each test

   it('should be created', () => {
    const service: UserService = TestBed.get(UserService);
    expect(service).toBeTruthy();
   });

   it('should have add function', () => {
    const service: UserService = TestBed.get(UserService);
    expect(service.addComments).toBeTruthy();
   });

});

它应该是这样的:

describe('UserService', () => {

  beforeEach(() => TestBed.configureTestingModule({
    imports: [HttpClientTestingModule], // <- notice that I remove the HttpClientModule
    providers: [UserService]
  }));

   it('should be created', () => {
    const service: UserService = TestBed.get(UserService);
    expect(service).toBeTruthy();
   });

   it('should have add function', () => {
    const service: UserService = TestBed.get(UserService);
    expect(service.addComments).toBeTruthy();
   });

});

关于javascript - Angular 6 服务无法通过单元测试(NullInjectorError : No provider for HttpClient!),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53066408/

相关文章:

java - Angular 客户端发布 Spring boot REST Api 请求

node.js - 如何在浏览器中使用 typescript ?

typescript - `is` 关键字在 typescript 中有什么作用?

javascript - 在提交时传递主键而不是属性

javascript - 更改颜色当前链接页面 Angular 和CSS

angular - Angular 中 *ngFor 和 MatDialog 的问题

angular - CSS 在表中插入伪元素并将其移到父边界的左/右

reactjs - 通用 Typescript 类型 + React hook

javascript - Turbolinks 加载事件在页面加载时不起作用

javascript - Mocha hooks 不仅在 WebStorm 中被部分识别