Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No provider for AngularFirestore

I am trying to use Karma and Jasmine to test my Angular5 that uses Firestore. However when I do "ng test", I get an error saying "NullInjectorError: No provider for AngularFirestore/AngularFireAuth/AuthService!". Following the post at NullInjectorError: No provider for AngularFirestore, I added AngularFirestore, AngularFireAuth, and AuthService to provider in app.module.ts, but that did not resolve the issue.

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 (the code for tests):

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!');
  }));
});

Any help is appreciated, thanks in advance.

like image 878
Rentian Dong Avatar asked Sep 10 '26 03:09

Rentian Dong


1 Answers

The service AngularFirestore relies on initialization of AngularFireModule and import of AngularFirestoreModule which you have done for your actual code.

For the test, you don't have that setup. Which is correct in the sense that ideally you shouldn't call out to actual firestore database from your test. So the solution is you need to stub the service.

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

};

Add whatever the methods you are using, this example doesn't have all available methods stubbed.

Then provide that stub:

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

Credit goes to @ksaifullah

like image 70
emanuel.virca Avatar answered Sep 12 '26 16:09

emanuel.virca



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!