我的控制器$rootScope.$on函数中有监听用户登录的功能。
$rootScope.$on('$firebaseSimpleLogin:login',function(e, authUser) {
User.findByUid(authUser.uid).then(function(user) {
我嘲笑‘用户’和'loginService‘服务。
beforeEach(inject(function($controller, $rootScope, $q) {
scope = $rootScope.$new();
q = $q;
headerCtrl = $controller('headerCtrl', {
$scope: scope,
loginService: _loginService,
User: _userService
});
}));
现在我想测试一下,当捕获用户登录时,User.findByUid将被调用。因此,我需要知道如何“模拟-模拟”这个$on方法,以便检查是否调用了findByUid方法。怎么请?我试过.
it('should call User.findByUid on $firebaseSimpleLogin:login', function() {
spyOn(scope, '$on');
// here I need to probably trigger it somehow...
// and check or?...
expect(scope.$on).toHaveBeenCalled();
});
更新 https://gist.github.com/TrkiSF2/39315e7ea980cac6cc9f
边题
当我将ctrl代码更改为:
$rootScope.$on('$firebaseSimpleLogin:login',function(e, authUser) {
User.findByUid(authUser.uid);
});
以及我的模拟用户服务:
findByUid: function(uid) {
console.log("dump");
}
我的测试是:
it('should call User.findByUid on $firebaseSimpleLogin:login', function() {
spyOn(_userService, 'findByUid');
var authUser = { uid: 1 };
scope.$emit('$firebaseSimpleLogin:login', authUser);
expect(_userService.findByUid).toHaveBeenCalled();
});
起作用了..。但是为什么控制台中没有“转储”消息,所以我可以确定测试使用的是我的模拟代码,而不是真正的代码。(如果有.),我想确定它不会执行某些DB查询。)
最后一个问题
如果我的ctrl代码看起来像:
$rootScope.$on('$firebaseSimpleLogin:login',function(e, authUser) {
User.findByUid(authUser.uid).then(function(user) {
User.setCurrentUser(user);
我想检查一下User.setCurrentUser是否也被调用了?做这件事最好的方法是什么?在一些单独的代码中还是在某种程度上相同的?
也许能回答我的问题?
出于好奇,我尝试了这样做,并在我的模拟用户对象中添加了新方法:
setCurrentUser: function(user) {
}
我已经兑现了我的诺言:
findByUid: function(uid) {
defered = q.defer();
defered.resolve({nick:'Trki'});
return defered.promise;
},
然后我更新了我的测试
it('should call User.findByUid on $firebaseSimpleLogin:login', function() {
spyOn(_userService, 'findByUid').and.callThrough();
spyOn(_userService, 'setCurrentUser');
var authUser = { uid: 1 };
scope.$emit('$firebaseSimpleLogin:login', authUser);
scope.$root.$digest();
expect(_userService.findByUid).toHaveBeenCalled();
expect(_userService.setCurrentUser).toHaveBeenCalled;
});
上面写着成功!这是好办法吗?
发布于 2014-04-27 02:52:24
用户模拟上的间谍:
spyOn(_userService, 'findByUid').and.callThrough();
然后使用$broadcast
或$emit
手动分派事件(取决于您从哪个范围分派)。如果需要,添加参数:
var authUser = { uid: 1 };
scope.$emit('$firebaseSimpleLogin:login', authUser);
进行核查:
expect(_userService.findByUid).toHaveBeenCalled();
在本例中,您需要使用and.callThrough()
,因为这里在链中添加了一个then
:
User.findByUid(authUser.uid).then(function(user) {
如果不让调用通过您的模拟将无法返回您定义的承诺:
findByUid: function(uid) {
defered = q.defer();
return defered.promise;
}
它将尝试对未定义的对象执行then
,因此“未定义的”不是一个对象。
侧问题-答案:
如果添加.and.callThrough();
,则应该执行console.log("dump")
。
如果不这样做,调用将被截获,有关调用的信息将被保存,但函数将不会实际执行。
这意味着,如果您监视自己的模拟,您几乎总是希望使用callThrough()
,因为它是返回模拟的数据。
这也意味着您并不总是需要自己的模拟,因为您可以在您的服务上设置一个间谍,真正的实现将不会被执行,因为调用将被拦截。
然后可以使用and.returnValue
和and.callFake
返回或执行模拟逻辑。
https://stackoverflow.com/questions/23322129
复制