2016-10-24 1 views
4

In meinem Angular 2 Anwendung wirft, ich bin die folgende Komponente zu Unit-Test versucht:Prüfung, dass eine Komponente richtig verhält, wenn der Dienst ruft eine Ausnahme mit kantigen 2

export class LoginComponent implements OnInit { 
    invalidCredentials = false; 
    unreachableBackend = false; 

    constructor(private authService: AuthService) {} 

    ngOnInit() { 
    this.invalidCredentials = false; 
    } 

    onSubmit(user: any) { 
    this.authService.authenticateUser(<User>user).subscribe((result) => { 
     if (!result) { 
     this.invalidCredentials = true; 
     } 
    }, (error) => { 
     if (error instanceof InvalidCredentialsError) { 
     this.invalidCredentials = true; 
     } else { 
     this.unreachableBackend = true; 
     } 
    }); 
    } 
} 

Ich habe bereits erfolgreich die getestet glücklicher Weg. Jetzt möchte ich überprüfen, dass, wenn authService.authenticateUser() einen Fehler auslöst, invalidCredentials und unreachableBackend korrekt eingestellt sind. Hier ist, was ich versuche:

describe('Authentication triggering an error',() => { 
    class FakeAuthService { 
    authenticateUser(user: User) { 
     throw new InvalidCredentialsError(); 
    } 
    } 

    let component: LoginComponent; 
    let fixture: ComponentFixture<LoginComponent>; 
    let authService: AuthService; 
    let spy: Spy; 

    beforeEach(() => { 
    TestBed.configureTestingModule({ 
     declarations: [LoginComponent], 
     providers: [ 
     {provide: AuthService, useClass: FakeAuthService}, 
     {provide: TranslateService, useClass: FakeTranslateService} 
     ], 
     imports: [ FormsModule, TranslateModule, AlertModule ] 
    }); 

    fixture = TestBed.createComponent(LoginComponent); 
    component = fixture.componentInstance; 
    authService = fixture.debugElement.injector.get(AuthService); 
    spy = spyOn(authService, 'authenticateUser').and.callThrough(); 
    }); 

    it('should not log in successfully if authentication fails',() => { 
    const user = {username: 'username', password: 'password'}; 
    component.onSubmit(user); 

    expect(authService.authenticateUser).toHaveBeenCalledWith(user); 
    expect(spy.calls.count()).toEqual(1, 'authenticateUser should have been called once'); 
    expect(component.invalidCredentials).toBe(true, 'credentials should be invalid because of the exception'); 
    expect(component.unreachableBackend).toBe(false, 'backend should be reachable at first'); 
    }); 
}); 

Aber wenn ich diesen Test ausführen, bekomme ich folgende Fehler an:

PhantomJS 2.1.1 (Mac OS X 0.0.0) Komponente: Anmeldung Authentifizierung auslösenden Ein Fehler sollte sich nicht erfolgreich anmelden, wenn die Authentifizierung fehlschlägt FEHLGESCHLAGEN [object Object] in src/test.ts (Zeile 49782) authenticateUser @ webpack: /// Benutzer/sarbogast/dev/myproject/frontend/src/app/login /login.component.spec.ts:112:44 < - src/test.ts: 49782: 67 onSubmit @ webpack: /// Benutzer/sarbogast/dev/myproject/frontend/sr c/app/login/login.component.ts: 9: 4896 < - src/test.ts: 85408: 5955 webpack: /// Benutzer/sarbogast/dev/myproject/frontend/src/app/login/login. component.spec.ts: 139: 25 < - src/test.ts: 49806: 31 [email protected]: ///Users/sarbogast/dev/myproject/frontend/~/zone.js/dist/zone.js: 203: 0 < - src/test.ts: 84251: 33 onInvoke @ webpack: ///Users/sarbogast/dev/myproject/frontend/~/zone.js/dist/proxy.js: 72: 0 < - src /test.ts:59204:45 [email protected]: ///Users/sarbogast/dev/myproject/frontend/~/zone.js/dist/zone.js: 202: 0 < - src/test.ts: 84250 : 42 run @ webpack: ///Users/sarbogast/dev/myproject/frontend/~/zone.js/dist/zone.js: 96: 0 < - src/test.ts: 84144: 49 webpack:/// Benutzer/sarbogas t/dev/meinprojekt/frontend/~/zone.js/dist/jasmine-patch.js: 91: 27 < - src/test.ts: 58940: 53 ausführen @ webpack: /// Benutzer/sarbogast/dev/myproject/frontend/~/zone.js/dist/jasmine-patch.js: 119: 0 < - src/test.ts: 58968: 46 ausführen @ webpack: /// Benutzer/sarbogast/dev/myproject/frontend/~/zone.js/dist/jasmine-patch.js: 119: 0 < - src/test.ts: 58968: 46 invokeTask @ webpack: /// Benutzer/sarbogast/dev/myproject/frontend/~/zone. js/dist/zone.js: 236: 0 < - Quelle/test.ts: 84284: 42 runTask @ webpack: ///Users/sarbogast/dev/myproject/frontend/~/zone.js/dist/zone. js: 136: 0 < - src/test.ts: 84184: 57 drainMicroTaskQueue @ webpack: ///Users/sarbogast/dev/myproject/frontend/~/zone.js/dist/zone.js: 368: 0 < - src/test.ts: 84416: 42 PhantomJS 2.1.1 (Mac OS X 0.0.0): 33 von 38 Ausgeführt (1 FAILED) (übersprungen 5) (0,704 Sekunden/0.842 Sekunden)

So offensichtlich etwas gibt, das ich nicht bekommen. Ich sollte die Tatsache erwähnen, dass ich völlig neu in der JS-Unit-Tests und etwas neu in der reaktiven Programmierung bin.

Antwort

2

Sie können das nicht tun, da der Fehler nur geworfen wird und zum Test überläuft. Was Sie tun müssen, ist, dem Benutzer das Abonnieren mit Rückrufen zu erlauben, und dann können Sie den Fehlerrückruf aufrufen.Zum Beispiel

class FakeAuthService { 
    authenticateUser(user: User) { 
    // return this service so user can call subscribe 
    return this; 
    } 

    subscribe(onNext, onError) { 
    if (onError) { 
     onError(new InvalidCredentialsError()); 
    } 
    } 
} 

Eine weitere Option ist Observable.throw(new InvalidCredentialsError())

authenticateUser(user: User) { 
    return Observable.throw(new InvalidCredentialsError()); 
} 

Diese verwenden wird jeder Teilnehmer onError Rückruf führen zu nennen. Persönlich mag ich die Verwendung des Mocks, der sich selbst zurückgibt. Ich kann den Mock konfigurierbarer machen, um das Testen zu erleichtern. Sehen Sie den folgenden Link für ein Beispiel, was ich meine.

Siehe auch:

+0

Vielen Dank, das Observable.throw() ist das, was ich fehlte, und ich denke, es simuliert, was mein wirklicher Dienst enger tut. Damit funktioniert es. – Sebastien

Verwandte Themen