首页 > 解决方案 > 使用 HTTPClient 添加服务后测试失败

问题描述

当我将BackendService添加到DashboardComponent 的构造函数时,我遇到了这个问题:

错误:StaticInjectorError(DynamicTestModule)[BackendService -> HttpClient]:StaticInjectorError(平台:核心)[BackendService -> HttpClient]:

NullInjectorError:没有 HttpClient 的提供者!

我有backend.service.ts我有这个:

  1 import { Injectable } from '@angular/core';
  2 import { HttpClient } from '@angular/common/http';
  3 import { Observable } from 'rxjs';
  4 import { environment } from '../environments/environment';
  5 
  6 @Injectable({
  7   providedIn: 'root'
  8 })  
  9 export class BackendService {
 10 
 11   constructor(private http: HttpClient) { }
 12 
 13   getUsers() : Observable<any> {
 14     return this.http.get<any>(`${environment.api}/api/users`);
 15   }   
 16 
 17 }

backend.service.spec.ts是这样的:

 1 import { TestBed, inject, async } from '@angular/core/testing';
  2 import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
  3 import { environment } from '../environments/environment';
  4 
  5 import { BackendService } from './backend.service';
  6 
  7 describe('BackendService', () => {
  8   let service : BackendService;
  9   let backend : HttpTestingController;
 10   
 11   beforeEach(() => {
 12     TestBed.configureTestingModule({
 13       imports : [HttpClientTestingModule],
 14       providers: [BackendService]
 15     });
 16   });
 17   
 18   it('should be created', inject([HttpTestingController, BackendService], (backend: HttpTestingController, service: BackendService) => {
 19     expect(service).toBeTruthy();
 20   }));
 21   
 22   it('should get users', inject([HttpTestingController, BackendService], (backend: HttpTestingController, service: BackendService) => {
 23     service.getUsers().subscribe();
 24     const req = backend.expectOne(`http://localhost:4000/api/users`);
 25     expect(req.request.method).toEqual('GET');
 26     backend.verify();
 27   }));
 28 });

我的仪表板组件

  1 import { Component, OnInit } from '@angular/core';
  2 import { BackendService } from '../backend.service';
  3 
  4 @Component({
  5   selector: 'app-dashboard',
  6   templateUrl: './dashboard.component.html',
  7   styleUrls: ['./dashboard.component.css']
  8 })  
  9 export class DashboardComponent implements OnInit {
 10       
 11   constructor(private backend : BackendService) { } // This makes the  error
 12   
 13   ngOnInit() {
 14   }
 15     
 16 } 

仪表板.component.spec.ts

  1 import { async, ComponentFixture, TestBed } from '@angular/core/testing';
  2 import { DashboardComponent } from './dashboard.component';
  3 
  4 describe('DashboardComponent', () => {
  5   let component: DashboardComponent;
  6   let fixture: ComponentFixture<DashboardComponent>;
  7 
  8   beforeEach(async(() => {
  9     TestBed.configureTestingModule({
 10       declarations: [ DashboardComponent ]
 11     })
 12     .compileComponents();
 13   }));
 14 
 15   beforeEach(() => {
 16     fixture = TestBed.createComponent(DashboardComponent);
 17     component = fixture.componentInstance;
 18     fixture.detectChanges();
 19   });
 20 
 21   it('should create', () => {
 22     expect(component).toBeTruthy();
 23   });
 24 });

这是我的app.moudule.ts

    1 import { BrowserModule } from '@angular/platform-browser';
    2 import { NgModule } from '@angular/core';
    3 import { HttpClientModule, HttpClient } from '@angular/common/http';
    4 
    5 import { AppRoutingModule, routingComponents } from './app-routing.module';
    6 import { AppComponent } from './app.component';
    7 
    8 @NgModule({
    9   declarations: [
   10     AppComponent,
   11     routingComponents
   12   ],
   13   imports: [
   14     BrowserModule,
   15     HttpClientModule,
   16     AppRoutingModule
   17   ],
   18   providers: [],
   19   bootstrap: [AppComponent]
   20 })
   21 export class AppModule { }
                                      

标签: angularangular6

解决方案


这就是您的dashboard.component.spec.ts最终应该是什么样子。

import { BackendService } from './../backend.service';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { HttpClientModule } from '@angular/common/http';
import { HttpClientTestingModule } from '@angular/common/http/testing';

import { DashboardComponent } from './dashboard.component';

describe('DashboardComponent', () => {
  let component: DashboardComponent;
  let fixture: ComponentFixture<DashboardComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ DashboardComponent ],
      providers: [BackendService],
      imports: [HttpClientModule, HttpClientTestingModule]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(DashboardComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

由于组件依赖于服务,而服务又依赖于HttpClient,因此您需要导入HttpClientAngular 提供的测试模块。然后,您需要将这些内容添加到调用中的providersandimports数组中TestBed.configureTestingModule。这使得所有HttpClient东西都可用于您需要的服务。

我只是对此进行了编码,对其进行了测试,并且测试成功了。

同样的模式也适用于组件依赖于使用HttpClient.


推荐阅读