Angular 6 - NullInjectorError: 在单元测试中未提供 HttpClient 的提供者

79

我正在服务中导入并使用HttpClient, 代码如下:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
    providedIn: 'root',
})
export class MyService {
    constructor(private http: HttpClient) { }

    getData() {
        return this.http.get("url...");
    }
}

然而,当我运行ng test来进行我的单元测试时,当这些测试使用该服务时,我收到以下错误:

Error: StaticInjectorError(DynamicTestModule)[HttpClient]: 
  StaticInjectorError(Platform: core)[HttpClient]: 
    NullInjectorError: No provider for HttpClient!

Angular 6 HTTP文档只是建议执行我上面所做的操作。


1
单元测试的代码是什么?这很重要。 - JB Nizet
可能是Angular 4错误:没有HttpClient提供程序的重复问题。 - Kevin Doyon
@KevinDoyon 不,我的问题是关于单元测试失败的,不是其他方面。 - Kingamere
4
这个重复的内容正是针对这个问题的 :) 你很可能没有在测试中导入HttpClientModule。你的测试会创建自己的模块。如果你没有在那里导入HttpClientModule(或者HttpClientTestingModule),HttpClient就无法工作,因为Angular不知道它的存在。即使你在比如AppModule中添加了HttpClientModule也没有用。它需要在TestBed.configureTestingModule中。如果你有一个SharedModule,也可以导入它,只要HttpClientModule在其中被exports了。但是测试会变慢,因为SharedModule中可能包含不必要的东西。 - Kevin Doyon
@KevinDoyon 没错,谢谢你,我只需要导入 HttpClientTestingModule 就好了。 - Kingamere
我导入了HttpClientTestingModule,但它不起作用。仍然找不到HttpClient... - undefined
3个回答

140
import { TestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import {HttpClientModule} from '@angular/common/http';
import { myService } from './myservice';


describe('myService', () => {

      beforeEach(() => TestBed.configureTestingModule({
        imports: [HttpClientTestingModule], 
        providers: [myService]
      }));

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

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

    });

15
谢谢,我只需要在configureTestingModule方法的imports数组中添加HttpClientTestingModule即可。 - Kingamere
3
这很有帮助,但是import {HttpClientModule} from '@angular/common/http';并不必要,因为测试类实际上并没有使用它。 - iowatiger08
1
谢谢!这在 Angular 9 中对我很有用。import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; beforeEach(() => TestBed.configureTestingModule({ imports: [HttpClientTestingModule], providers: [myService] })); - Hassan Raza
7
提供解释这个方案的加成效果和原因将会有所帮助。如果没有文字说明,我就只能在原帖和答案之间进行视觉差异比较了。 - bob
我像这样导入了HttpClientTestingModule,但它不起作用。还是找不到HttpClient。 - undefined
显示剩余5条评论

1
import { TestBed } from '@angular/core/testing';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { myService } from './myservice';

describe('HeaderService', () => {
  beforeEach(() => TestBed.configureTestingModule({
    imports: [ HttpClientTestingModule ],
    providers: [myService]
  }));
});

0

你应该将HttpClient添加到声明你的组件的模块的导入中

@NgModule({
  declarations: [
    MyComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpClientModule
  ],
  providers: []
})
export class AppModule { }

更新:

import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; 必须被包含在单元测试中。

OP的问题没有遵循单元测试指南。在 beforeEach 中必须导入 HttpClientTestingModule。

  beforeEach(() => TestBed.configureTestingModule({
    imports: [HttpClientTestingModule], 
    providers: [dataService]  
  }));

基本上,HttpClientTestingModule 被注入到 dataService 中用于单元测试目的,以防止 StaticInjectorError 错误。


2
用户要求进行单元测试...但不在服务中使用它 - Takatalvi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接