2017-07-15 12 views
2

AngularFireAuthに依存するサービス(AuthService)を単体テストしようとしているサークルを回っています。単位AngularFireAuthとMockingを使用するサービスのテストauthState

実際にFirebaseと対話しているサービスではなく、Observable AngularFireAuth.authStateを模擬する方法を見つけようとしています。ここで

は私のテスト仕様である:

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

そして、ここでは私の(単純化)サービスです。

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(); 
    } 
} 

私はそれがあるが、私ドンエラーにもちろんProperty 'authState' is private and only accessible within class 'AuthService'.

を取得します実際にそれにアクセスしたい - 私はそれを模擬したりハイジャックして、私のテスト仕様の中からその価値をコントロールできるようにしたい。私はここで自分のコードとは別の道にあると信じています。

注意AngularFire2のバージョン^4を使用しています。ここに記載されています:https://github.com/angular/angularfire2/blob/master/docs/version-4-upgrade.md

答えて

2

封入されたメンバーを反映​​することができます。

難しい方法:

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

簡単な方法:

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

はありがとうございます。どうすれば 'authState'も設定できますか?サービス内の 'currentUid'ゲッターをテストしたいとします。乾杯。 –

+1

ようこそ。同様に、 'Reflect.set(...) 'を使用します。あるいはもっと簡単に、 'service ['authState'] = ...'または '(service as any).authState = ...'。純粋にTS質問のように見えますが、ここでは関連しているので 'typescript'タグを' firebase'の代わりに質問に追加することをお勧めします。 – estus

+0

素晴らしい!ちょうど自分自身を教育する。 (AngularFireAuth、useValue:mockAngularFireAuth)を実行しなくなりましたが、Firebaseへの呼び出しがどうして来ないのですか?サービスの 'init'は匿名ユーザーを作成する必要があります。それは(テスト中に - 私はアプリを実行するとき)はないが、それは素晴らしいですが、なぜですか? –

関連する問題