AngularJS、CoffeeScript、および Jasmine (WebStorm で編集) を使用して、promise のチェーンを単体テストしたいと思います。
次のサンプル サービスがあるとします。
Angular サービス
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
このサービスを使用すると、メソッドcallSteps()
をスコープにアタッチできます。このメソッドが呼び出されると、サードパーティ API への一連の非同期 $http 呼び出しが実行されます。
各ステップが少なくとも呼び出されることをテストするために、次の Jasmine 仕様を作成しました。
ジャスミンスペック
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()
このテストの結果は次のとおりです。
- 期待する (@exampleService.step1).toHaveBeenCalled() - PASS
- 期待する (@exampleService.step2).toHaveBeenCalled() -失敗
step2()
テスト中に正常に実行する方法を教えてください。
ありがとうございました
編集
以下の@Dashuは、問題に対する回答を親切に提供してくれました。秘訣は、Promise チェーンの解決を呼び出すscope.$apply
かscope.$digest
トリガーするだけです。
これが実際のテスト フラグメントです。
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()