我如何窥探用茉莉花的角链的承诺 [英] How do I spy on an Angular promise chain using Jasmine

查看:159
本文介绍了我如何窥探用茉莉花的角链的承诺的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆