使用AngularJS,CoffeeScript和Jasmine(在WebStorm中编辑),我想对一系列承诺进行单元测试。
假设我有以下示例服务:
角色服务
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规范。
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()
该测试的结果如下:
你能告诉我如何让step2()
成功地接受考验吗?
谢谢
修改
@Dashu以下提供了问题的答案。诀窍是简单地调用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()
答案 0 :(得分:3)
在第二次预期之前尝试$ rootScope。$ apply()
也是关于defer.resolve()的。我不知道这是否真的解决了这个承诺,我认为它只是设置了它在结算时返回的值。
所以我会把这个转移到$ q.defer()调用之下,然后将promise传递给andReturn()
你可以做defer.resolve(true),defer.reject(false),所以如果你的承诺会在insinde callsteps中被拒绝,那么将返回true或false