angularjs – 为什么$q.when在使用ngMock时包装第三方承诺时无法解决?

前端之家收集整理的这篇文章主要介绍了angularjs – 为什么$q.when在使用ngMock时包装第三方承诺时无法解决?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
鉴于以下服务:

angular.module('app',[])
  .service('promisey',function ($q) {
    this.cakey = function () {
      return $q.when('brownie')
    }
    this.fruity = function () {
      return $q.when(Promise.resolve('apple'))
    }
  })

……以及以下测试:

var self = this

describe('when',function () {
  var promisey
  var $rootScope

  beforeEach(module('app'))
  beforeEach(inject(function(_$rootScope_,_promisey_) {
    promisey = _promisey_
    $rootScope = _$rootScope_
  }))

  it('should give cakes',function (done) {
    promisey.cakey()
      .then(function (cake) {
        expect(cake).toBe('brownie')
      })
      .catch(self.fail.bind())
      .finally(done)
    $rootScope.$apply()
  })

  it('should give fruit',function (done) {
    promisey.fruity()
      .then(function (cake) {
        // XXX: does not resolve
        expect(cake).toBe('apple')
      })
      .catch(self.fail.bind())
      .finally(done)
    $rootScope.$apply()
  })
})

…当ngMock来源时,promisey.fruity()永远不会解决.如果我没有源ngMock(并自己处理angular.injector),测试将按预期解决.这是为什么?

可以在tlvince/q-when-reduced-test-case找到该问题的简化测试用例.

解决方法

这是因为本机promise使用与Angular不同的调度程序.角度调度通过其异步队列上的evalAsync进行承诺.不同的promise库可能会以不同的方式调度promise – 在本机promise的用例中,它通过称为“microtask队列”的东西进行调度.

当你调用$rootScope.$应用它“刷新evalAsync队列”,因为运行摘要周期,这模拟“异步”并让你测试promises.

你不能用本机承诺“欺骗”计时器,所以你必须编写一个实际上是异步的测试.

您不能使用ngMock并使用Mocha的promise语法:

it('should give fruit',function () { // no done
    return promisey.fruity() // see return here
      .then(function (cake) {
        expect(cake).toBe('apple')
      });
      // no digest,no `done`
  });

我觉得它看起来好多了:)

猜你在找的Angularjs相关文章