鉴于以下服务:
2015-09-16 18:24:52 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
......以及以下测试:
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
),则测试将按预期解决。那是为什么?
可以在tlvince/q-when-reduced-test-case找到此问题的简化测试用例。
答案 0 :(得分:3)
这是因为本机承诺使用与Angular不同的调度程序。 Angular schedule通过evalAsync
在其异步队列上进行承诺。不同的承诺库可能会以不同的方式安排承诺 - 在本机承诺的使用情况下,它通过称为"微任务队列"。
当您致电$rootScope.$apply
时,它会刷新evalAsync队列"由于运行了摘要周期,因此可以模拟" async"并让你测试承诺。
你不能欺骗"这种方式使用本机承诺定时器,因此您必须编写一个实际上异步的测试。
您无法使用ngMock并使用Mocha的承诺语法:
it('should give fruit', function () { // no done
return promisey.fruity() // see return here
.then(function (cake) {
expect(cake).toBe('apple')
});
// no digest, no `done`
});
我认为它看起来好多了:))