【问题标题】:Test promise with delay延迟测试承诺
【发布时间】:2025-12-07 03:45:01
【问题描述】:

我正在尝试测试一个接受承诺作为参数的方法,但这个承诺永远不会解决! 代码:

function blockQueueUntilResolved (aPromise) {
  aPromise.finally(releaseBlock)
  queueBlocked = true
}

function releaseBlock () {
  // other things..
}

测试:

describe('given ...', function () {
  var initDefer
  var initPromise
  var fn1
  var fn2
  var promise1Resolved = false
  var promise2Resolved = false

  it('queueBlocked is set to true', function () {
    // initDefer = $q(function (resolve) {
    //   initPromise = resolve
    // })
    initDefer = $q.defer()
    // initPromise = initDefer.promise

    fn1 = function () {
      console.log('fn1 called')
      promise1Resolved = true
    }

    fn2 = function () {
      console.log('fn2 called')
      promise2Resolved = true
    }

    QueueService.blockQueueUntilResolved(initDefer.promise)
    QueueService.push(fn1)
    QueueService.push(fn2)

    expect(QueueService.isBlocked()).to.be.true
  })

  it('promises in the queue are not processed', function () {
    expect(promise1Resolved).to.be.false
    expect(promise2Resolved).to.be.false
  })

  describe('when the blocked promise is resolved', function () {
    it('resolve', function () {
      // initPromise()
      initDefer.resolve()
    })

    it('promises in the queue are processed', function () {
      expect(promise1Resolved).to.be.true
      expect(promise2Resolved).to.be.true
    })
  })
})

我尝试了两种策略来承诺,使用 defer 和使用这个构造函数,但没有一个有效。 promise1Resolvedpromise2Resolved 始终为 false,不会调用相关日志。 怎么了??

【问题讨论】:

    标签: javascript angularjs unit-testing mocha.js


    【解决方案1】:

    好的,问题出在角度本身。 $q 服务依赖于$digest 服务,因此在调用摘要之前不会解析承诺。

    解决方法是:

    describe('given ...', function () {
      var initDefer
      var fn1
      var fn2
      var promise1Resolved = false
      var promise2Resolved = false
    
      it('queueBlocked is set to true', function () {
        initDefer = $q.defer()
    
        fn1 = function () {
          console.log('fn1 called')
          promise1Resolved = true
        }
    
        fn2 = function () {
          console.log('fn2 called')
          promise2Resolved = true
        }
    
        QueueService.blockQueueUntilResolved(initDefer.promise)
        QueueService.push(fn1)
        QueueService.push(fn2)
    
        expect(QueueService.isBlocked()).to.be.true
        // make some assertions
        expect(promise1Resolved).to.be.false
        expect(promise2Resolved).to.be.false
    
        initDefer.resolve()
        // call the $digest
        $rootScope.$digest()
        // now the promise is resolved
    
        expect(promise1Resolved).to.be.true
        expect(promise2Resolved).to.be.true
      })
    })
    

    您可以找到更多信息here

    【讨论】: