我一直在试图单独测试依赖于AngularFireAuth的服务(AuthService).
我试图找到一种方法来模拟或高举Observable AngularFireAuth.authState而不是实际与Firebase交谈的服务.
这是我的测试规范:
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',(service: AuthService) => { expect(service.authState).toBe(null); })); });
这是我的(简化)服务:
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(); } }
我得到错误属性’authState’是私有的,只能在类’AuthService’中访问.
当然是,但我不想实际访问它 – 我想模拟或劫持它,所以我可以从我的测试规范中控制它的价值.我相信我的代码在这里偏离了我的道路.
请注意我使用的是AngularFire2的版本^ 4,并且引入了重大更改;记录在这里:https://github.com/angular/angularfire2/blob/master/docs/version-4-upgrade.md
封装成员可以反映出来.
困难的方式:
expect(Reflect.get(service,'authState')).toBe(null);
简单的方法:
expect(service['authState']).toBe(null); expect((service as any).authState).toBe(null);