问题描述
我有一个角度服务类: -
I have an angular service class : -
angular.module('triggerTips')
.service('userData', function ($rootScope, $http, $log, $firebase) {
this._log = {
service : 'userData'
};
// Synchronized objects storing the user data
var config;
var userState;
// Loads the user data from firebase
this.init = function(readyCallback) {
var log = angular.extend({}, this._log);
log.funct = 'init';
var fireRef = new Firebase('https://XYZfirebaseio.com/' + $rootScope.clientName);
config = $firebase(fireRef.child('config')).$asObject();
userState = $firebase(fireRef.child('userState').child($rootScope.userName)).$asObject();
Promise.all([config.$loaded(), userState.$loaded()]).
then(
function() {
if(config == null || Object.keys(config).length < 4) {
log.message = 'Invalid config';
$log.error(log);
return;
}
if(!userState.userProperties) {
userState.userProperties = {};
}
if(!userState.contentProperties) {
userState.contentProperties = {};
}
log.message = 'User Properties: ' + JSON.stringify(userState.userProperties);
$log.debug(log);
log.message = 'Content Properties: ' + JSON.stringify(userState.contentProperties);
$log.debug(log);
log.message = 'Loaded user data from firebase';
$log.debug(log);
readyCallback();
},
function() {
log.message = 'Unable to load user data from firebase';
$log.error(log);
}
);
};
// Returns the initial tip configuration
this.getConfig = function() {
return config;
};
// Set the value of a user property
// A user property is something about the user himself
this.setUserProperty = function(property, value) {
if(!userState.userProperties) {
userState.userProperties = {};
}
userState.userProperties[property] = value;
userState.$save();
$rootScope.$broadcast('user-property-change', property);
};
// Get the value of a user property
this.getUserProperty = function(property) {
if(userState.userProperties) {
return userState.userProperties[property];
}
};
// Set the value of a user content property
// A content property is something about a particular peice of content for a particular user
this.setContentProperty = function(contentName, property, value) {
if(!userState.contentProperties[contentName]) {
userState.contentProperties[contentName] = {};
}
userState.contentProperties[contentName][property] = value;
userState.$save();
$rootScope.$broadcast('content-property-change', contentName, property);
};
// Increment a count property on the user state for a given tip
this.incrementContentProperty = function(contentName, property) {
if(!userState.contentProperties[contentName]) {
userState.contentProperties[contentName] = {};
}
if(!userState.contentProperties[contentName][property]) {
userState.contentProperties[contentName][property] = 0;
}
userState.contentProperties[contentName][property]++;
userState.$save();
$rootScope.$broadcast('content-property-change', contentName, property);
};
// Returns the user state for a given tip and property
this.getContentProperty = function(contentName, property) {
if(userState.contentProperties) {
var t = userState.contentProperties[contentName];
if(t) {
return t[property];
}
}
};
});
我正在尝试使用jasmine对此服务进行单元测试: -
I am trying to unit test this service using jasmine:-
我的单元测试是: -
my unit test is :-
'use strict';
describe('Service: userData', function () {
// load the service's module
beforeEach(function() {
module('triggerTips');
});
// instantiate service
var userData;
beforeEach(inject(function (_userData_) {
userData = _userData_;
}));
it('should load correctly', function () {
expect(!!userData).toBe(true);
});
describe('after being initialized', function () {
beforeEach(function(done) {
// Unable to get this working because the callback is never called
userData.init(function() {
done();
});
jasmine.DEFAULT_TIMEOUT_INTERVAL = 2000;
});
it('should have a valid config', function (done) {
setTimeout(function() {
expect(Object.keys(userData.getConfig()).length == 0);
done();
}, 1500);}); }); });
我读到了Jasmine中的异步支持,但我对使用JavaScript进行单元测试不太感兴趣让它工作。
I read about the Asynchronous Support in Jasmine, but as I am rather new to unit testing with JavaScript couldn't make it work.
我收到一个错误:
有人可以帮我提供工作示例我的代码有一些解释?
Can somebody help me providing working example of my code with some explanation?
推荐答案
我建议你用<$替换 setTimeout
c $ c> $ timeout 以加快您的规格套件。您需要成为规范套件的一部分才能使其按预定方式运行,但似乎已经考虑到了你的规格。好东西。
I would suggest that you replace setTimeout
with $timeout
so as to speed up your spec suite. You will need ngMock to be a part of your spec suite in order to get this working the intended way, but that seems to have already been taken care of looking at your spec. Good stuff.
然后为了使规范离开的异步性质你会打电话:
Then in order to make the async nature of the spec "go away" you would call:
其中延迟
是可选的。
- 如果没有延迟通过,所有挂起的异步任务(角度世界中的 )将完成他们正在做的事情。
- 如果延迟通过,指定延迟内的所有待处理任务将完成。超出指定延迟的那些将保持待定状态。
- If no delay is passed, all the pending async tasks (inside the angular world) will finish what they're doing.
- If a delay is passed, all pending tasks within the specified delay will finish. Those outside of the specified delay will remain in a 'pending' state.
有了这个,你可以删除完成
回调并按如下方式编写测试:
With this, you can remove the done
callback and write your tests as such:
describe('after being initialized', function () {
var $timeout;
beforeEach(function () {
// Unable to get this working because the callback is never called
userData.init();
inject(function ($injector) {
$timeout = $injector.get('$timeout');
});
}));
it('should have a valid config', function () {
$timeout.flush();
// callback should've been called now that we flushed().
expect(Object.keys(userData.getConfig()).length).toEqual(0);
});
});
您使用的是什么承诺
实施?我看到对 Promise.all
的调用,但为了继续我的回答,我将假设它相当于 $ q.all
。运行 $ timeout.flush
应该注意解决这些值。
What Promise
implementation are you using? I see a call to Promise.all
but for the sake of continuing on with my answer I'm going to assume it is equivalent to $q.all
. Running $timeout.flush
should take care of resolving those values.
如果你想对拒绝写下期望/在茉莉花承诺的解析的值,我会去了解一下像
jsfiddle
这篇关于错误:超时 - 在指定的超时时间内未调用异步回调.... .DEFAULT_TIMEOUT_INTERVAL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!