Wie kann ich Spion auf einem Eckigen Versprechen Kette mit Jasmin
Verwendung von AngularJS, CoffeeScript und Jasmin (bearbeitet in WebStorm), würde ich gern unit-Tests eine Kette von Versprechungen.
Können sagen, ich habe das folgende Beispiel service:
Angular Service
class ExampleService
stepData: []
constructor: (@$http) ->
attachScopeMethod: (@scope) ->
@scope.callSteps = => @step1().then -> @step2()
step1: ->
@$http.get('app/step/1').then (results) =>
@stepData[0] = results.data
results
step2: ->
@$http.get('app/step/2').then (results) =>
@stepData[2] = results.data
results
Dieser service ermöglicht es mir, zu befestigen, die Methode callSteps()
zu dem Bereich. Diese Methode, wenn Sie aufgerufen, führt eine Reihe von asynch $http-Aufrufe zu einer 3rd-party-API.
Testen, dass jeder Schritt ist zumindest genannt, habe ich Folgendes geschrieben Jasmine spec.
Jasmine Spec
ddescribe 'ExampleService', ->
beforeEach ->
module 'myApp'
beforeEach inject ($rootScope, $injector) ->
@scope = $rootScope.$new()
@exampleService = $injector.get 'exampleService'
@q = $injector.get '$q'
describe 'process example steps', ->
beforeEach ->
@exampleService.attachScopeMethod(@scope)
it "should attach the scope method", ->
expect(@scope.callSteps).toBeDefined()
describe 'when called should invoke the promise chain', ->
it "should call step1 and step2", ->
defer = @q.defer()
@exampleService.step1 = jasmine.createSpy('step1').andReturn(defer.promise)
@exampleService.step2 = jasmine.createSpy('step2')
@scope.callSteps()
defer.resolve()
expect(@exampleService.step1).toHaveBeenCalled()
expect(@exampleService.step2).toHaveBeenCalled()
Die Ergebnisse dieses Tests ist wie folgt:
- erwarten(@exampleService.Schritt 1).toHaveBeenCalled() - PASS
- erwarten(@exampleService.step2).toHaveBeenCalled() - SCHEITERN
Können Sie mir sagen, wie ich bekommen kann step2()
zu erfolgreich führen im test?
Danke
BEARBEITEN
@Dashu unten freundlicherweise die Antwort auf das problem. Der trick ist, rufen Sie einfach scope.$apply
oder scope.$digest
auslösen, die Versprechen chain-Auflösung.
So, hier ist der working test-fragment.
describe 'when called should invoke the promise chain', ->
it "should call step1 and step2", ->
defer = @q.defer()
defer.resolve()
@exampleService.step1 = jasmine.createSpy('step1').andReturn(defer.promise)
@exampleService.step2 = jasmine.createSpy('step2')
@scope.callSteps()
@scope.$apply()
expect(@exampleService.step1).toHaveBeenCalled()
expect(@exampleService.step2).toHaveBeenCalled()
Du musst angemeldet sein, um einen Kommentar abzugeben.
versuchen Sie, ein $rootScope.$Anwendung (die) vor dem zweiten erwarten
ebenfalls zu verschieben.resolve(). ich weiß nicht, ob dies tatsächlich löst das Versprechen, das ich denke, dass es nur setups der Wert, der zurückgegeben wird, wenn Sie verrechnet wird.
also ich würde zu bewegen, die bis kurz unterhalb der $q.defer() aufrufen, bevor man die Versprechen, die andReturn()
könnten Sie nicht aufzuschieben.beheben(true), aufschieben.Ablehnung(false), also, wenn Sie Versprechen, wird abgelehnt bekommen insinde callsteps, true oder false zurückgegeben werden
apply()
Tat es. Mein Fehler war zu denken, dass dieresolve()
Methode tatsächlich gelöst werden, die Versprechen, aber es scheint, dass es existiert, um set-up der return-Wert (oder Funktion) werden ausgelöst, wenn die Versprechen tatsächlich gelöst worden ist. Wenn Sie keine der vorformuliertenresolve()
dann das Versprechen nicht beheben, müssen Sie beideapply()
undresolve()
.