为什么我的TestBed提供者不覆盖真实服务?

时间:2019-12-22 12:14:13

标签: angular testing dependency-injection jasmine

我正在尝试测试具有依赖性的简单组件。我正在尝试模拟这种依赖关系,但实际的服务仍在构建中。有人可以发现我在想什么吗?

这是我的组成部分:

import { Component } from "@angular/core";
import { AuthService } from "src/app/services/auth.service.js";

@Component({
  selector: "app-auth-form",
  template: ""
})
export class AuthFormComponent {
  constructor(private authService: AuthService) {}
}

这取决于此AuthService

import { Injectable } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { UserModule } from "../user/user.module";

@Injectable({
  providedIn: "root"
})
export class AuthService {
  constructor(private http: HttpClient) {}

  registerUser(email: string, password: string): Promise<UserModule> {
    return null;
  }
}

请注意,该通知取决于HttpClient

现在我的测试如下:

import { async, TestBed } from "@angular/core/testing";
import { AuthFormComponent } from "./auth-form.component";
import { AuthService } from "src/app/services/auth.service";

describe("AuthFormComponent", () => {
  beforeEach(async(() => {
    const authServiceSpy = jasmine.createSpyObj("AuthService", [
      "registerUser"
    ]);

    TestBed.configureTestingModule({
      declarations: [AuthFormComponent],
      providers: [{ provide: AuthService, useValue: authServiceSpy }]
    }).compileComponents();
  }));

  it("should create", () => {
    let component = TestBed.createComponent(AuthFormComponent)
      .componentInstance;
    expect(component).toBeTruthy();
  });
});

在这里,请参阅第{ provide: AuthService, useValue: authServiceSpy }行,因此,我希望不会构建实际的AuthService。但是当我运行测试时,出现以下错误:

Chrome 78.0.3904 (Windows 10.0.0) AuthFormComponent should create FAILED
        NullInjectorError: StaticInjectorError(DynamicTestModule)[HttpClient]: 
          StaticInjectorError(Platform: core)[HttpClient]: 
            NullInjectorError: No provider for HttpClient!
        error properties: Object({ ngTempTokenPath: null, ngTokenPath: [ Function ], ngDebugContext: DebugContext_({ view: Object({ def: Object({ factory: Function, nodeFlags: 33603585, rootNodeFlags: 33554433, nodeMatchedQueries: 0, flags: 0, nodes: [ Object({ nodeIndex: 0, parent: null, renderParent: null, bindingIndex: 0, outputIndex: 0, checkIndex: 0, flags: 33554433, childFlags: 49152, directChildFlags: 49152, childMatchedQueries: 0, matchedQueries: Object({  }), matchedQueryIds: 0, references: Object({  }), ngContentIndex: null, childCount: 1, bindings: [  ], bindingFlags: 0, outputs: [  ], element: Object({ ns: '', name: 'app-auth-form', attrs: [  ], template: null, componentProvider: Object({ nodeIndex: 1, parent: <circular reference: Object>, renderParent: <circular reference: Object>, bindingIndex: 0, outputIndex: 0, checkIndex: 1, flags: 49152, childFlags: 0, directChildFlags: 0, childMatchedQueries: 0, matchedQueries: Object, matchedQueryIds: 0, references: Object, ngContentIndex: -1, childCount: 0 ...
            at <Jasmine>
            at NullInjector.get (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:855:1)
            at resolveToken (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:17514:1)
            at tryResolveToken (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:17440:1)
            at StaticInjector.get (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:17266:1)
            at resolveToken (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:17514:1)
            at tryResolveToken (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:17440:1)
            at StaticInjector.get (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:17266:1)
            at resolveNgModuleDep (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:30393:1)
            at NgModuleRef_.get (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:31578:1)
            at injectInjectorOnly (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:734:1)
Chrome 78.0.3904 (Windows 10.0.0): Executed 3 of 3 (1 FAILED) (0 secs / 0.077 secs)
Chrome 78.0.3904 (Windows 10.0.0) AuthFormComponent should create FAILED
        NullInjectorError: StaticInjectorError(DynamicTestModule)[HttpClient]: 
          StaticInjectorError(Platform: core)[HttpClient]: 
            NullInjectorError: No provider for HttpClient!
        error properties: Object({ ngTempTokenPath: null, ngTokenPath: [ Function ], ngDebugContext: DebugContext_({ view: Object({ def: Object({ factory: Function, nodeFlags: 33603585, rootNodeFlags: 33554433, nodeMatchedQueries: 0, flags: 0, nodes: [ Object({ nodeIndex: 0, parent: null, renderParent: null, bindingIndex: 0, outputIndex: 0, checkIndex: 0, flags: 33554433, childFlags: 49152, directChildFlags: 49152, childMatchedQueries: 0, matchedQueries: Object({  }), matchedQueryIds: 0, references: Object({  }), ngContentIndex: null, childCount: 1, bindings: [  ], bindingFlags: 0, outputs: [  ], element: Object({ ns: '', name: 'app-auth-form', attrs: [  ], template: null, componentProvider: Object({ nodeIndex: 1, parent: <circular reference: Object>, renderParent: <circular reference: Object>, bindingIndex: 0, outputIndex: 0, checkIndex: 1, flags: 49152, childFlags: 0, directChildFlags: 0, childMatchedQueries: 0, matchedQueries: Object, matchedQueryIds: 0, references: Object, ngContentIndex: -1, childCount: 0 ...
            at <Jasmine>
            at NullInjector.get (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:855:1)
            at resolveToken (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:17514:1)
            at tryResolveToken (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:17440:1)
            at StaticInjector.get (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:17266:1)
            at resolveToken (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:17514:1)
            at tryResolveToken (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:17440:1)
            at StaticInjector.get (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:17266:1)
            at resolveNgModuleDep (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:30393:1)
            at NgModuleRef_.get (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:31578:1)
Chrome 78.0.3904 (Windows 10.0.0): Executed 3 of 3 (1 FAILED) (0.096 secs / 0.077 secs)

在我看来,这似乎是在尝试构造真实的AuthService,但没有依赖关系。任何指针都很棒!

编辑

我在StarBlitz-https://angular-wrk4yi.stackblitz.io中重新创建了场景,但是在此情况下工作正常。所以它一定在我的某个地方。

1 个答案:

答案 0 :(得分:0)

编辑

最终想通了!问题出在进口。在我的组件中,我有:

import { AuthService } from "src/app/services/auth.service";

而不是:

TestBed.overrideProvider(AuthService, { useValue: authServiceSpy})

因此,我假设它从dist文件夹加载了javascript版本,然后提供的类型化基础不起作用。


我不知道是什么提供了原始服务,但是找到了解决方法:

{{1}}

根据名称,此名称将覆盖真实服务提供商的来源。而且我不再需要支持真正的AuthService依赖项+主要是受测类实际上在这里使用我的间谍!