2017-09-16 4 views
-1

In meiner Angular2 App, die AngularFire2 verwendet, habe ich eine AuthService, die versucht, anonym mit Firebase zu authentifizieren.Test für das Versäumnis, ein Observable mit Jasmine zu abonnieren

Ich versuche, einen Test zu schreiben, der das Abonnement der AngularFireAuth 's authState schlägt fehlschlägt (eine außergewöhnliche Beendigung der beobachtbaren Sequenz) und einen Fehler ausgelöst werden.

Ich habe gefragt, was scheint ein similar question zu sein, aber hier bin ich für eine "außergewöhnliche Beendigung der beobachtbaren Sequenz" - eine katastrophale Fehler z. wenn der Drittanbieter Firebase nicht verfügbar ist.

Dies ist getrennt von meiner anderen (verwandten) Frage, wo ich auf ein abgelehntes Versprechen teste.

Hier ist ein AuthService vereinfacht:

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: firebase.User) => { 
     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); 
    }); 
    } 
} 

Und hier sind meine Testspezifikt:

import { TestBed, inject } from '@angular/core/testing'; 

import { AngularFireAuth } from 'angularfire2/auth'; 
import 'rxjs/add/observable/of'; 
import { Observable } from 'rxjs/Rx'; 

import { AuthService } from './auth.service'; 
import { environment } from '../environments/environment'; 

describe('AuthService',() => { 
    const mockAngularFireAuth: any = { 
    auth: jasmine.createSpyObj('auth', { 
     'signInAnonymously': Promise.resolve('foo'), 
     // 'signInWithPopup': Promise.reject(), 
     // 'signOut': Promise.reject() 
    }), 
    authState: Observable.of(null) 
    }; 

    beforeEach(() => { 
    TestBed.configureTestingModule({ 
     providers: [ 
     { provide: AngularFireAuth, useValue: mockAngularFireAuth }, 
     { provide: AuthService, useClass: AuthService } 
     ] 
    }); 
    }); 

    it('should be created', inject([ AuthService ], (service: AuthService) => { 
    expect(service).toBeTruthy(); 
    })); 

    // 
    // 
    // 
    // 
    // 

    describe('when we can’t authenticate',() => { 
    beforeEach(() => { 
     mockAngularFireAuth.auth.signInAnonymously.and.returnValue(Promise.reject('bar')); 
    }); 

    it('should thow', inject([ AuthService ], (service: AuthService) => { 
     expect(service).toThrow(); 
    })); 
    }); 

    // 
    // 
    // 
    // 
    // 

}); 

Ich bin mir nicht sicher, ob dies überhaupt möglich ist, oder benötigt - da dies eine sein würde sehr außergewöhnlicher Fall. Wenn ich mit dem Testen beginne, möchte ich aber, dass die Tests so umfassend und wasserdicht wie möglich sind! Danke für Ihre Hilfe!

+0

Mögliches Duplikat [Test für abgelehnte Versprechen mit Jasmin] (https://stackoverflow.com/questions/46252850/test- für-abgelehnt-Versprechen-mit-Jasmin) – jonrsharpe

+0

Danke @jonrsharpe, aber das ist kein Betrogener; Dieses Q fragt, wie eine Testspezifikation geschrieben wird, die erwartet, dass ein Fehler ausgelöst wird, wenn eine "außergewöhnliche Beendigung der beobachtbaren Sequenz" vorliegt, wenn versucht wird, den "authState" von AngularFireAuth zu abonnieren. Prost –

+0

@jonrsharpe du hast meine beiden Fragen abgelehnt? Sie sind keine Duplikate und ich fühle, dass sie die Probleme klar erklären; was das gewünschte Ergebnis ist und kurze Code-Beispiele haben. Können Sie mir vorschlagen, wie ich die Fragen verbessern könnte? Können Sie helfen? –

Antwort

0

Ich musste mockAngularFireAuth 's authState ausspionieren und ein Observable zurückgeben, das einen Fehler auslöst. Als ich nach mockAngularFireAuth.authState in der onError Funktion zeichnen, soll ich den Fehler erwarten, a la:

import { TestBed, async, inject } from '@angular/core/testing'; 

import { AngularFireAuth } from 'angularfire2/auth'; 
import 'rxjs/add/observable/of'; 
import { Observable } from 'rxjs/Rx'; 

import { AuthService } from './auth.service'; 
import { MockUser} from './mock-user'; 
import { environment } from '../environments/environment'; 

describe('AuthService',() => { 
    // An anonymous user 
    const authState: MockUser = { 
    displayName: null, 
    isAnonymous: true, 
    uid: '17WvU2Vj58SnTz8v7EqyYYb0WRc2' 
    }; 

    const mockAngularFireAuth: any = { 
    auth: jasmine.createSpyObj('auth', { 
     'signInAnonymously': Promise.reject({ 
     code: 'auth/operation-not-allowed' 
     }), 
     // 'signInWithPopup': Promise.reject(), 
     // 'signOut': Promise.reject() 
    }), 
    authState: Observable.of(authState) 
    }; 

    beforeEach(() => { 
    TestBed.configureTestingModule({ 
     providers: [ 
     { provide: AngularFireAuth, useValue: mockAngularFireAuth }, 
     { provide: AuthService, useClass: AuthService } 
     ] 
    }); 
    }); 

    it('should be created', inject([ AuthService ], (service: AuthService) => { 
    expect(service).toBeTruthy(); 
    })); 

    … 

    describe('catastrophically fails',() => { 
    beforeEach(() => { 
     const spy = spyOn(mockAngularFireAuth, 'authState'); 

     spy.and.returnValue(Observable.throw(new Error('Catastrophe'))); 
    }); 

    describe('AngularFireAuth.authState',() => { 
     it('should invoke it’s onError function',() => { 
     mockAngularFireAuth.authState.subscribe(null, 
      (error: Error) => { 
      expect(error).toEqual(new Error('Catastrophe')); 
      }); 
     }); 
    }); 
    }); 
    … 
}); 
Verwandte Themen