Hid*_*per 16 javascript unit-testing asynchronous angularjs
我正在尝试对具有异步方法但没有运气的服务进行单元测试.
我试图通过使用angularjs中的$ q支持来实现promises.
任何帮助,将不胜感激.
angular.module('myapp', ['myservice']);
angular.module('myservice', []).factory('myservice', function($q) {
var ls = {};
ls.DoIt = function() {
var deferred = $q.defer();
setTimeout(function(){
deferred.resolve(5);
},3000);
return deferred.promise;
}
return ls;
});
describe('services', function () {
beforeEach(module('myservice'));
it("should equal 2", inject(function(myservice) {
myservice.DoIt().then(function(returned) {
expect(returned).toEqual(2);
});
}));
});
Run Code Online (Sandbox Code Playgroud)
pko*_*rce 30
首先,setTimeout由于难以模拟,因此测试特别棘手.幸运的是,AngularJS有一个包装器($timeout),它起着相同的作用但可以很容易地模拟:
ls.DoIt = function() {
var deferred = $q.defer();
$timeout(function(){
deferred.resolve(5);
},3000);
return deferred.promise;
}
Run Code Online (Sandbox Code Playgroud)
提供的模拟$timeout允许我们轻松模拟已用时间(with $timeout.flush()),这意味着我们的测试可以快速运行,而无需等待异步事件完成(请注意,生产代码仍在使用异步API!).
更改的测试看起来像:
it("should equal 5", inject(function(myservice, $timeout) {
var valueToVerify;
myservice.DoIt().then(function(returned) {
valueToVerify = returned;
});
$timeout.flush();
expect(valueToVerify).toEqual(5);
}));
Run Code Online (Sandbox Code Playgroud)
最后工作的jsFiddle:http://jsfiddle.net/v9L9G/1/