无极解决了angularjs茉莉测试为时已晚 [英] Promise resolved too late in angularjs jasmine test
问题描述
我写了下面的测试茉莉与 NG-描述
与运行人缘
。
I have the following jasmine test written with ng-describe
, run with karma
.
(我使用PhantomJS ES6-承诺填充工具)
(I am using es6-promise polyfill for PhantomJS)
var myModule = angular.module('MyModule', []);
myModule.service('MyService', [function() {
return {
getItems: function() {
// this will be spied and mocked
}
};
}]);
myModule.controller('MyController', ['$scope', 'MyService',
function($scope, MyService) {
$scope.items = [];
$scope.refreshItems = function() {
MyService.getItems().then(
function ok(items) {
$scope.items = items;
console.log('OK, items.length = ' + items.length);
},
function fail(reason) {
console.error('FAIL')
}).catch(console.error.bind(console));
};
}
]);
ngDescribe({
name: "MyController test",
modules: ['MyModule'],
inject: ['MyService', '$rootScope', '$q'],
controllers: 'MyController',
tests: function(deps) {
function getPromise(val) {
return new Promise(function(resolve, reject) {
resolve(val);
});
}
it('updates $scope.items', function() {
spyOn(deps.MyService, 'getItems').and.returnValue(getPromise([4, 5, 6]));
deps.MyController.refreshItems();
deps.$rootScope.$digest();
expect(deps.MyService.getItems).toHaveBeenCalled();
expect(deps.MyController.items.length).toBe(3);
console.log("END OF TEST");
});
}
});
该测试将失败,因为承诺解决太晚了:
The test would fail because the promise is resolved too late:
LOG: 'END OF TEST'
PhantomJS 1.9.8 (Windows 7 0.0.0) MyController test updates $scope.items FAILED
Expected 0 to be 3.
at d:/git/myproject/test/controllers/ItmngtControllerTest.js:49
LOG: 'OK, items.length = 3'
PhantomJS 1.9.8 (Windows 7 0.0.0): Executed 37 of 37 (1 FAILED) (0.085 secs / 0.26 secs)
在太长时间的调查,我想它,如果我用 $ Q
而不是无极
,它会工作罚款。
After too long investigation, I figured it that if I use $q
instead of Promise
, it will work fine.
function getPromise(val) {
var deferred = deps.$q.defer();
deferred.resolve(val);
return deferred.promise;
}
不过,我想知道,为什么是这样的话,我可以改变的东西在我的测试中使用无极
而不是 $ Q <的/ code>来使测试通过?
I'm wondering however, why is this the case, and can I change something in my test to use Promise
instead of $q
to make the test pass?
我读过在不同的地方约 $ rootScope。$适用()
,但无论我把它,它仍然不为我工作。
I've read in various places about $rootScope.$apply()
but wherever I put it, it still doesn't work for me.
推荐答案
角 $ Q
测试是同步的,这是一个巨大的优势。一旦范围 $消化()
被调用,可以预期,所有的 $ Q
承诺链中处理程序也被调用。
Angular $q
testing is synchronous, which is a huge advantage. Once scope $digest()
was called, the one can expect that all $q
promise chain handlers were called also.
承诺在一般(包括ES6实现)是通过设计异步,另一方面。一旦承诺就解决了,它的处理器将在下一次滴答被调用。那么愉快角测试是不是同步的了:
Promises in general (including ES6 implementation) are asynchronous by design, on the other hand. Once the promise was resolved, its handlers will be called on the next tick. So pleasant Angular testing is not that synchronous anymore:
it('updates $scope.items', function (done) {
...
setTimeout(() => {
expect(deps.MyService.getItems).toHaveBeenCalled();
expect(deps.MyController.items.length).toBe(3);
console.log("END OF TEST");
done();
});
});
无极
可以嘲笑为测试目的是同步的,的 模拟承诺
可能在这种情况下使用。
Promise
can be mocked for testing purposes to be synchronous, mock-promises
may be used in this case.
和有 茉莉合作
其目的是进行异步测试的茉莉花容易多了(它实际上)与ES6发电机和合
,我不知道它有多好与<$ C $执行C> NG-描述。
And there is jasmine-co
which is intended to make asynchronous testing in Jasmine easier (and it actually does) with ES6 generators and co
, I'm not aware how good it performs with ng-describe
.
这篇关于无极解决了angularjs茉莉测试为时已晚的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!