I spun around trying to unit test a Service ( AuthService ), which depends on AngularFireAuth .
I'm trying to find a way to mock or make fun of Observable AngularFireAuth.authState instead of the Service actually talking to Firebase.
Here is my test spec:
import { inject, TestBed } from '@angular/core/testing'; import { AngularFireModule } from 'angularfire2'; import { AngularFireAuth, AngularFireAuthModule } from 'angularfire2/auth'; import * as firebase from 'firebase/app'; import 'rxjs/add/observable/of'; // import { BehaviorSubject } from 'rxjs/BehaviorSubject'; import { Observable } from 'rxjs/Rx'; import { AuthService } from './auth.service'; import { environment } from '../../environments/environment'; const authState: firebase.User = null; const mockAngularFireAuth: any = { authState: Observable.of(authState) }; describe('AuthService', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [AngularFireModule.initializeApp(environment.firebaseAppConfig)], providers: [ { provider: AngularFireAuth, useValue: mockAngularFireAuth }, AuthService ] }); }); it('should be defined', inject([ AuthService ], (service: AuthService) => { expect(service).toBeDefined(); })); it('.authState should be null', inject([ AuthService ], (service: AuthService) => { expect(service.authState).toBe(null); })); });
And here is my (simplified) service:
import { Injectable } from '@angular/core'; import { AngularFireAuth } from 'angularfire2/auth'; import * as firebase from 'firebase/app'; import { Observable } from 'rxjs/Rx'; @Injectable() export class AuthService { private authState: firebase.User; constructor(private afAuth: AngularFireAuth) { this.init(); } private init(): void { this.afAuth.authState.subscribe((authState) => { if (authState === null) { this.afAuth.auth.signInAnonymously() .then((authState) => { this.authState = authState; }) .catch((error) => { throw new Error(error.message); }); } else { this.authState = authState; } }, (error) => { throw new Error(error.message); }); } public get currentUser(): firebase.User { return this.authState ? this.authState : undefined; } public get currentUserObservable(): Observable<firebase.User> { return this.afAuth.authState; } public get currentUid(): string { return this.authState ? this.authState.uid : undefined; } public get isAnonymous(): boolean { return this.authState ? this.authState.isAnonymous : false; } public get isAuthenticated(): boolean { return !!this.authState; } public logout(): void { this.afAuth.auth.signOut(); } }
I get the error Property 'authState' is private and only accessible within class 'AuthService'.
Of course it is, but I donβt really want to access it - I want to mock it or pull it out so that I can control its value from my test specification. I believe I'm learning with my code here.
Note that I am using version ^4 for AngularFire2, and changes have been made; documented here: https://github.com/angular/angularfire2/blob/master/docs/version-4-upgrade.md
source share