I'm new to unit tests and I haven't been able to find a clear and concise explanation of what gets added as a provider vs import in my spec.ts. I keep getting the same error no matter what I try.
Here's my service class:
import { Injectable } from '@angular/core';
import { Auth, createUserWithEmailAndPassword, signInWithEmailAndPassword, UserCredential } from '@angular/fire/auth';
import { FormGroup } from '@angular/forms';
import { Router } from '@angular/router';
import { signOut } from '@firebase/auth';
import { AlertController } from '@ionic/angular';
import { getFirestore, collection, addDoc } from 'firebase/firestore';
import { getApp } from 'firebase/app';
import { DocumentData, DocumentReference } from '@angular/fire/firestore';
@Injectable({
providedIn: 'root'
})
export class AuthService {
userCollection = collection(getFirestore(getApp()), 'users');
constructor(private auth: Auth,
private router: Router,
private alertController: AlertController) { }
async register(registrationForm: FormGroup): Promise<UserCredential> {
return await createUserWithEmailAndPassword(this.auth, registrationForm.value.email, registrationForm.value.password);
}
async login(email: string, password: string): Promise<UserCredential> {
return await signInWithEmailAndPassword(this.auth, email, password);
}
logout(): Promise<void> {
return signOut(this.auth);
}
async authenticationAlert(message: any, header: string, route: string): Promise<void> {
const alert = await this.alertController.create({
subHeader: `${header}`,
message: `${message}`,
buttons: [
{
text: 'Ok',
role: 'Ok',
cssClass: 'secondary',
handler: () => {
this.router.navigateByUrl(`${route}`);
}
}
]
});
await alert.present();
}
saveProfile(uid: string, email: string, displayName: string): Promise<DocumentReference<DocumentData>> {
return addDoc(this.userCollection, {uid, email, displayName});
}
}
Here's the spec:
import { TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AuthService } from './auth.service';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { getApp } from '@angular/fire/app';
import { signOut } from '@angular/fire/auth';
import { addDoc, collection, DocumentReference, getFirestore } from '@angular/fire/firestore';
describe('AuthService', () => {
let service: AuthService;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ ReactiveFormsModule, FormsModule, RouterTestingModule,],
providers: [AuthService]
});
service = TestBed.inject(AuthService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
And this is the error I keep getting:
AuthService > should be created
NullInjectorError: R3InjectorError(DynamicTestModule)[AuthService -> Auth -> Auth]:
NullInjectorError: No provider for Auth!
error properties: Object({ ngTempTokenPath: null, ngTokenPath: [ 'AuthService', 'Auth', 'Auth' ] })
NullInjectorError: R3InjectorError(DynamicTestModule)[AuthService -> Auth -> Auth]:
NullInjectorError: No provider for Auth!
at NullInjector.get (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2020/core.mjs:9081:27)
at R3Injector.get (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2020/core.mjs:9248:33)
at R3Injector.get (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2020/core.mjs:9248:33)
at injectInjectorOnly (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2020/core.mjs:4868:33)
at ɵɵinject (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2020/core.mjs:4872:12)
at Object.factory (ng:///AuthService/ɵfac.js:4:39)
at R3Injector.hydrate (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2020/core.mjs:9343:35)
at R3Injector.get (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2020/core.mjs:9237:33)
at NgModuleRef.get (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2020/core.mjs:22399:33)
at TestBedRender3.inject (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2020/testing.mjs:26537:52)
Expected undefined to be truthy.
Error: Expected undefined to be truthy.
at <Jasmine>
at UserContext.apply (http://localhost:9876/_karma_webpack_/webpack:/src/app/services/auth.service.spec.ts:22:21)
at _ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:409:30)
at ProxyZoneSpec.onInvoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-testing.js:303:43)
Additionally, I'm getting this error in ever spec.ts on every component that imports the AuthService.
I'm not sure how to determine out of all of my imports which ones I'll have to include in the spec file. And how do I determine if they get injected as a provider or import?