2017-08-02 4 views
2

Ich versuche derzeit, eine Funktion zu testen, die einen http-Anfragedienst aufruft und dann etwas im Abonnement-Teil (ruft eine Funktion und setzt eine Variable). Mein Ansatz war bisher, nur die Funktion aufzurufen und ich dachte, der Request-Service wird automatisch aufgerufen und der Subscribe-Part wird ausgeführt. Ich habe jedoch das Gefühl, dass dies nicht der richtige Weg ist, da es nicht funktioniert.Angular2 - Testen Sie eine Funktion, die einen HTTP-Dienst innerhalb

Die Funktion, die ich testen wollen:

public trainBot() { 
    this.isTraining = true; 
    this.requestsService.trainModel(this.botId, false) 
     .subscribe(response => { 
     this.trainingStatus = this.trainingStatusMapping[response['status']]; 
     this.pollTrainingStatus(); 
     }); 
    } 

Mein Test bisher (was nicht funktioniert).

it('should poll the training status',() => { 
    spyOn(component, 'pollTrainingStatus').and.callThrough(); 
    component.trainBot(); 
    fixture.detectChanges(); 
    expect(component.pollTrainingStatus).toHaveBeenCalled(); 
    }); 

Also, kann mir jemand sagen, wie innerhalb der .subscribe diesen Teil zu testen (... Teil

Update:?

als jemand vorgeschlagen, dass ich hinzugefügt und return async meinen . Test Sie arbeiten immer noch nicht, aber wie das nun auf der Suche:

it('should poll the training status', fakeAsync(() => { 
    component.trainBot(); 
    spyOn(service, 'trainModel').and.returnValue(Observable.of({'status': 'training'})); 
    spyOn(component, 'pollTrainingStatus').and.callThrough(); 
    fixture.detectChanges(); 
    tick(1); 
    expect(service.trainModel).toHaveBeenCalled(); 
    expect(component.pollTrainingStatus).toHaveBeenCalled(); 
    })); 

der Fehler ist die gleiche

+0

Können Sie den Fehler, den Sie erhalten, oder die Ausgabe für den fehlgeschlagenen Test teilen? – Kevin

+0

@Kevin "Erwarteter Spy PollTrainingStatus wurde aufgerufen." Was bedeutet, dass pollTrainingStatus() nicht aufgerufen wurde – threxx

+0

Überprüfen Sie diese Frage: [angular2 testing mit Jasmine für Abonnement-Methode] (https://stackoverflow.com/questions/40080912/angular2-testing-using-jasmine-for-subscribe-method) .Lass mich wissen, ob die Antwort dort für dich funktioniert. – Kevin

Antwort

4

Zum einen müssen Sie Ihre Spies erstellen, bevor Sie die Methode trainBot() ausgeführt werden. Das sollte deine Tests reparieren.

it('should poll the training status',() => { 
    spyOn(service, 'trainModel').and.returnValue(Observable.of({'status': 'training'})); 
    spyOn(component, 'pollTrainingStatus'); 

    component.trainBot(); 

    expect(service.trainModel).toHaveBeenCalled(); 
    expect(component.pollTrainingStatus).toHaveBeenCalled(); 
})); 

Lassen Sie uns jedoch über Ihre Teststrategien sprechen.

Um ehrlich zu sein, testen Sie eine Komponente, nicht den Dienst, so dass Sie die Service-Methode nicht durchgehen lassen sollten.

spyOn(service, 'trainModel').and.returnValue(Observable.of({'status': 'training'})); 

Darüber hinaus sollte ein Komponententest die kleinste mögliche Sache testen. Sie testen hier den Callback, und der Callback sollte wahrscheinlich eine benannte Methode anstelle einer anonymen Pfeilfunktion sein. Dann können Sie die Funktionalität des Rückrufs in anderen Tests testen und verifizieren.

public trainBot() { 
    this.isTraining = true; 
    this.requestsService.trainModel(this.botId, false) 
     .subscribe(response => this.onTrainbotSuccess(response)); 
} 

public onTrainbotSuccess(response) { 
    this.trainingStatus = this.trainingStatusMapping[response['status']]; 
    this.pollTrainingStatus(); 
} 

In dieser Test können Sie testen, ob die Antwort Methode

it('should call service.trainModel',() => { 
    spyOn(service, 'trainModel').and.returnValue(Observable.of({'status': 'training'})); 

    component.trainBot(); 

    expect(service.trainModel).toHaveBeenCalled(); 
}); 

it('should send success responses to onTrainbotSuccess()',() => { 
    spyOn(component, 'onTrainbotSuccess'); 
    spyOn(service, 'trainModel').and.returnValue(Observable.of({'status': 'training'})); 

    component.trainBot(); 

    expect(component.onTrainbotSuccess).toHaveBeenCalled(); 
}); 

Jetzt können wir Tests für speziell was bedeutet der Erfolg Rückruf schreiben genannt zu werden.

it('should poll the training status',() => { 
    spyOn(component, 'pollTrainingStatus'); 

    component.onTrainbotSuccess({'status': 'training'}); 

    expect(component.pollTrainingStatus).toHaveBeenCalled(); 
}); 
+0

oh ich hab es! Das macht viel mehr Sinn! Vielen Dank! – threxx

0

Die an subscribe() übergebene Funktion wird asynchron aufgerufen. Dies bedeutet, dass Ihre Assertion ausgeführt wird, bevor this.pollTrainingStatus() aufgerufen wird. Sie müssen async() or fakeAsync() utility function verwenden.

In-Code kann wie folgt aussehen (wenn fakeAsync() verwenden):

import { fakeAsync } from '@angular/core/testing'; 

it('should poll the training status', fakeAsync(() => { 
    ... 
    expect(component.pollTrainingStatus).toHaveBeenCalled(); 
})); 
+0

Ich fügte hinzu, dass immer noch nicht funktioniert, das gleiche Testergebnis – threxx

+0

Haben Sie 'tick()' wie in [docs] (https://angular.io/guide/testing#the-fakeasync-function) hinzugefügt? – buoto

+0

ja ich probierte es mit tick() und tick (1) – threxx

Verwandte Themen