【问题标题】:No provider for AngularFirestore没有 AngularFirestore 的提供者
【发布时间】:2018-08-11 17:19:40
【问题描述】:

我正在尝试使用 Karma 和 Jasmine 来测试我使用 Firestore 的 Angular5。但是,当我执行“ng 测试”时,我收到一条错误消息“NullInjectorError: No provider for AngularFirestore/AngularFireAuth/AuthService!”。在NullInjectorError: No provider for AngularFirestore 的帖子之后,我在 app.module.ts 中将 AngularFirestore、AngularFireAuth 和 AuthService 添加到提供程序,但这并没有解决问题。

app.module.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { AuthService} from './core/auth.service';

// Routing and routes import
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

// Authentication Module
import { CoreModule } from './core/core.module';

// Firebase imports
import { environment } from '../environments/environment';
import { AngularFireModule } from 'angularfire2';
import { AngularFirestoreModule } from 'angularfire2/firestore';
import { AngularFireAuthModule } from 'angularfire2/auth';
import { AngularFireAuth } from 'angularfire2/auth';
import { AngularFireStorageModule } from 'angularfire2/storage';
import { UserProfileComponent } from './user-profile/user-profile.component';
import { ProjectsComponent } from './projects/projects.component';
import { AngularFirestore } from 'angularfire2/firestore';

@NgModule({
  declarations: [
    AppComponent,
    UserProfileComponent,
    ProjectsComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    AngularFireModule.initializeApp(environment.firebase, "life-planner"),
    AngularFirestoreModule,
    AngularFireAuthModule,
    AngularFireStorageModule,
    FormsModule,
    CoreModule,
    AuthService,
    AngularFirestore,
    AngularFireAuth
  ],
  providers: [
    AngularFirestore,
    AuthService,
    AngularFireAuth,

  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

tsconfig.json

{
  "compileOnSave": false,
  "compilerOptions": {
    "paths": {
      "@angular/*": [
        "../node_modules/@angular/*"
      ]
    },
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es5",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2017",
      "dom"
    ]
  }
}

app.component.spec.ts(测试代码):

import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from './app.component';
import { RouterTestingModule } from '@angular/router/testing';
import { 
  AngularFirestore,
  AngularFirestoreCollection,
  AngularFirestoreDocument 
} from 'angularfire2/firestore';
import { NgModule } from '@angular/core';

describe('AppComponent', () => {
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ AppComponent ],
      imports: [ 
        RouterTestingModule
      ]
    }).compileComponents();
  }));
  it('should create the app', async(() => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.debugElement.componentInstance;
    expect(app).toBeTruthy();
  }));
  it(`should have as title 'app'`, async(() => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.debugElement.componentInstance;
    expect(app.title).toEqual('app');
  }));
  it('should render title in a h1 tag', async(() => {
    const fixture = TestBed.createComponent(AppComponent);
    fixture.detectChanges();
    const compiled = fixture.debugElement.nativeElement;
    expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!');
  }));
});

任何帮助表示赞赏,在此先感谢。

【问题讨论】:

  • 当您运行测试时,您使用的是测试模块,您必须在其中包含所有内容TestBed.configureTestingModule

标签: angular firebase jasmine karma-jasmine


【解决方案1】:

AngularFirestore 服务依赖于 AngularFireModule 的初始化和您为实际代码所做的 AngularFirestoreModule 的导入。

对于测试,您没有该设置。在理想情况下,您不应该从测试中调用实际的 Firestore 数据库,这是正确的。所以解决方案是你需要存根服务。

const FirestoreStub = {
collection: (name: string) => ({
  doc: (_id: string) => ({
    valueChanges: () => new BehaviorSubject({ foo: 'bar' }),
    set: (_d: any) => new Promise((resolve, _reject) => resolve()),
  }),
}),

};

添加您正在使用的任何方法,此示例并未包含所有可用的方法。

然后提供该存根:

TestBed.configureTestingModule({
  providers: [
    { provide: AngularFirestore, useValue: FirestoreStub },
  ],
});

归功于@ksaifullah

【讨论】:

  • 我被困在这里,我试图让 Karma 运行购买它总是失败说“NullInjectorError: No provider for AngularFirestore”。我发现这是唯一的答案。但我不能让它工作。
  • 我找到了,这就是答案。现在我有一个“TypeError:this.afs.collection(...).snapshotChanges 不是函数”。有什么想法吗?
【解决方案2】:

接受的答案是正确的,但如果有人愿意,他/她可以从您的测试中调用实际的 Firestore 数据库。只需以这种方式配置 TestBed:

TestBed.configureTestingModule({
        imports: [
            AngularFireAuthModule,
            AngularFirestoreModule,
            AngularFireStorageModule,
            AngularFireModule.initializeApp(Config.firebaseConfig),
        ],
        providers: [AngularFirestore]
    });

所以...事实上,您可以使用 Karma 和 Jasmine 针对您的真实数据库运行单元测试。

【讨论】:

    猜你喜欢
    • 2018-05-02
    • 2017-08-13
    • 2012-07-07
    • 2018-06-29
    • 2017-06-04
    • 2018-04-24
    • 2017-03-01
    • 2019-07-05
    • 1970-01-01
    相关资源
    最近更新 更多