Unit Testing Service using AngularFireAuth and Mocking authState

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

+2
source share
1 answer

Encapsulated items may be mirrored.

Hard way:

 expect(Reflect.get(service, 'authState')).toBe(null); 

A simple way:

 expect(service['authState']).toBe(null); expect((service as any).authState).toBe(null); 
+2
source

Source: https://habr.com/ru/post/1274382/


All Articles