我如何窥探用茉莉花的角链的承诺 [英] How do I spy on an Angular promise chain using Jasmine
问题描述
使用AngularJS,CoffeeScript的和Jasmine(在WebStorm编辑),我想进行单元测试的诺言链。
可以说我有下面的例子服务:
角服务
类ExampleService
stepData:[]
构造器:(@ $ HTTP) - GT; attachScopeMethod:(@Scope) - >
@ scope.callSteps = => @步骤1(),然后 - 过夜。; @第2步() 第一步: - >
@ $ http.get(应用程序/步/ 1),然后(结果)=>
@stepData [0] = results.data
结果 第二步: - >
@ $ http.get(应用程序/步/ 2'),然后(结果)=>
@stepData [2] = results.data
结果
这个服务允许我到一个方法 callSteps()
附加到的范围。这种方法被调用时,执行一系列的非同步$ HTTP调用第三方API。
要测试每一步都至少叫,我写了下面的茉莉花规范。
茉莉花规格
ddescribe'ExampleService', - > beforeEach - >
模块'对myApp beforeEach注入($ rootScope,$注射器) - >
@Scope = $ rootScope $新的()
@exampleService = $ injector.get'exampleService
@q = $ injector.get'$ Q' 描述过程示例步骤', - >
beforeEach - >
@ exampleService.attachScopeMethod(@Scope) 它应重视的范围方法, - >
期待(@ scope.callSteps).toBeDefined() 形容叫应该调用的承诺时链条', - > 它应该调用第一步和第二步 - >
推迟= @ q.defer()
@ exampleService.step1 = jasmine.createSpy('第一步')。andReturn(defer.promise) @ exampleService.step2 = jasmine.createSpy('第二步') @ scope.callSteps()
defer.resolve() 期待(@ exampleService.step1).toHaveBeenCalled()
期待(@ exampleService.step2).toHaveBeenCalled()
此试验的结果如下:
- 预期(@ exampleService.step1).toHaveBeenCalled() - 的 PASS 的
- 预期(@ exampleService.step2).toHaveBeenCalled() - 的 FAIL 的
您能告诉我怎样才能得到第二步()
来成功地在测试中运行?
感谢您
修改
@Dashu敬请下面提供的答案的问题。诀窍是简单地调用范围。$适用
或范围。$摘要
来触发承诺链解决方案。
因此,这里的工作测试片段。
描述'叫的时候应该调用的承诺链, - >
它应该调用第一步和第二步 - >
推迟= @ q.defer()
defer.resolve() @ exampleService.step1 = jasmine.createSpy('第一步')。andReturn(defer.promise)
@ exampleService.step2 = jasmine.createSpy('第二步') @ scope.callSteps()
@范围。$适用() 期待(@ exampleService.step1).toHaveBeenCalled()
期待(@ exampleService.step2).toHaveBeenCalled()
尝试$之前rootScope。$适用()的第二期待
也即将defer.resolve()。我不知道如果这实际上解决了承诺,我认为它只是设置值时,它解析返回。
所以我会动议,截至只是下面的$ q.defer()调用,传递的诺言对andReturn()之前
您可以做defer.resolve(真),defer.reject(假),所以如果你的承诺将被拒绝insinde callsteps,真的还是假的,将返回
Using AngularJS, CoffeeScript and Jasmine (edited in WebStorm), I would like to unit test a chain of promises.
Lets say I have the following example 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
This service allows me to attach a the method callSteps()
to the scope. This method, when called, executes a series of asynch $http calls to a 3rd party API.
To test that each step is at least called, I have written the following 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()
The results of this test is as follows:
- expect(@exampleService.step1).toHaveBeenCalled() - PASS
- expect(@exampleService.step2).toHaveBeenCalled() - FAIL
Can you tell me how I can get step2()
to succesfully run under test?
Thank you
EDIT
@Dashu below kindly supplied the answer to the problem. The trick is to simply call scope.$apply
or scope.$digest
to trigger the promise chain resolution.
So here is the 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()
try a $rootScope.$apply() before the second expect
also about defer.resolve(). i don't know if this actually resolves the promise, i think it just setups the value to return when it resolves.
so i would move that up to just underneath the $q.defer() call, before passing the promise to the andReturn()
you could do defer.resolve(true), defer.reject(false), so if you're promise will get rejected insinde callsteps, true or false will be returned
这篇关于我如何窥探用茉莉花的角链的承诺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!