2017-09-16 1 views
-1

Dans mon application Angular2 qui utilise AngularFire2, j'ai un AuthService qui essaie de s'authentifier anonymement avec Firebase. J'essaye d'écrire un test qui s'attend à l'échec de l'abonnement au AngularFireAuthauthState (une fin exceptionnelle de la séquence observable) et une erreur à être jetée.Test pour l'échec de s'abonner à un Observable avec Jasmine

J'ai demandé à ce qui semble être un similar question, cependant, ici, je suis en train de tester une "fin exceptionnelle de la séquence observable" - une défaillance catastrophique, par ex. lorsque le fournisseur tiers Firebase est arrêté.

Ceci est distinct de mon autre question (connexe) où je teste une promesse rejetée.

Voici une version simplifiée AuthService:

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

Et voici mes spécifications de test:

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

    // 
    // 
    // 
    // 
    // 

}); 

Je ne sais pas si cela est encore possible, ou nécessaire - que ce serait cas très exceptionnel. Si je vais commencer à tester, je voudrais que les tests soient aussi complets et étanches que possible! Merci de votre aide!

+0

double possible de [Test de promesse rejetée avec Jasmine] (https://stackoverflow.com/questions/46252850/test- for-rejected-promise-with-jasmine) – jonrsharpe

+0

Merci @jonrsharpe mais ce n'est pas dupe; ce Q demande comment écrire une spécification de test qui s'attend à ce qu'une erreur soit levée quand il y a une 'fin exceptionnelle de la séquence observable' en essayant de s'abonner à 'authState' de' AngularFireAuth'. Cheers –

+0

@ jonrsharpe vous avez voté à la fois mes questions? Ils ne sont pas des doublons et je pense qu'ils expliquent clairement les problèmes; quel est le résultat souhaité et avoir des exemples de code concis. Pourriez-vous suggérer comment je pourrais améliorer les questions? Êtes-vous en mesure d'aider? –

Répondre

0

J'avais besoin d'espionner mockAngularFireAuthauthState et renvoyer un Observable qui jette une erreur. Quand je souscris à mockAngularFireAuth.authState dans la fonction onError j'attendre l'erreur, à 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')); 
      }); 
     }); 
    }); 
    }); 
    … 
});