我正在尝试使用茉莉花间谍来测试$emit
发出的角度事件。
以下测试:
describe('DashboardCtrl', function () {
var scope, httpBackend, domainService;
beforeEach(module('bignibou', 'dashboard', 'utils'));
beforeEach(inject(function ($controller, $rootScope, _domainService_, messageService, $httpBackend) {
domainService = _domainService_;
scope = $rootScope.$new();
$controller('DashboardCtrl', {
$scope: scope,
domainService: domainService,
messageService: messageService,
currentUserAccount: {data: {firstName: 'John'}},
unreadMessagesCount: 0,
latestMessages: []
});
spyOn(scope, '$emit');
spyOn(scope, '$on');
spyOn(domainService, 'currentUserAccount').and.returnValue(function () {
var deferred = $q.defer();
deferred.resolve({id: 42, firstName: 'Pedro'});
return deferred.promise;
});
httpBackend = $httpBackend;
httpBackend.whenGET('/api/utils/current-useraccount').respond({id: 42, firstName: 'Pedro'});
}));
it('should handle user account updated', function () {
scope.$emit('useraccount:updated');
expect(scope.$on).toHaveBeenCalled();
expect(domainService.currentUserAccount).toHaveBeenCalled();
expect(scope.currentUserAccount.firstName).toEqual('Pedro');
});
});
的产率:
PhantomJS 1.9.8 (Mac OS X 0.0.0) DashboardCtrl should handle user account updated FAILED
TypeError: 'undefined' is not an object (evaluating 'spyOn(domainService, 'currentUserAccount').and.returnValue')
at /Users/julien/Documents/projects/bignibou/bignibou-site/bignibou-client/test/unit/dashboard.spec.js:17
at invoke (/Users/julien/Documents/projects/bignibou/bignibou-site/bignibou-client/src/bower_components/angular/angular.js:4473)
at workFn (/Users/julien/Documents/projects/bignibou/bignibou-site/bignibou-client/src/bower_components/angular-mocks/angular-mocks.js:2426)
undefined
Expected spy $on to have been called.
Expected spy currentUserAccount to have been called.
Expected 'John' to equal 'Pedro'.
PhantomJS 1.9.8 (Mac OS X 0.0.0): Executed 1 of 1 (1 FAILED) ERROR (0.005 secs / 0.034 secs)
来自我的域名服务:
currentUserAccount: function () {
return $http.get('/api/utils/current-useraccount', {
cache: false
});
},
来自DashboardCtrl:
$scope.$on('useraccount:updated', function () {
domainService.currentUserAccount().success(function (data) {
$scope.currentUserAccount = data;
});
});
我不确定自己错了什么。任何人都可以告诉我为什么不调用$on
监听器功能?
答案 0 :(得分:1)
在调用spyOn(scope, '$on')
之前需要$controller
,因为在控制器构造函数中调用了$on
。但是既然你想窥探听众,你可以这样做:
$controller('DashboardCtrl', ...);
listeners = scope.$$listeners['useraccount:updated'];
spyOn(listeners, 0);
在it
:
scope.$emit('useraccount:updated');
expect(listeners[0]).toHaveBeenCalled();
答案 1 :(得分:0)
正如您所见,$ scope。$ on函数有两个参数:
这意味着$ scope。$ on会在Controller初始化时调用,而不是在事件发出时调用。
因此,如果您想检查您的函数是否被调用,您可以执行以下操作:
将您的函数添加到$ scope(或变量)
$ scope.update = function(){ domainService.currentUserAccount()。success(function(data){ $ scope.currentUserAccount = data; }); }
列出项目
$ scope。$ on('useraccount:updated',$ scope.update);
修改你的测试:
spyOn($ scope,'update'); 期望(scope.update).toHaveBeenCalled();
希望这是有道理的
答案 2 :(得分:0)
我意识到我的测试实际上不需要任何茉莉花间谍。
我只想确保在$scope
上设置正确的值,如下所示:
describe('DashboardCtrl', function () {
var scope, httpBackend;
beforeEach(module('bignibou', 'dashboard', 'utils'));
beforeEach(inject(function ($controller, $rootScope, domainService, messageService, $httpBackend) {
scope = $rootScope.$new();
$controller('DashboardCtrl', {
$scope: scope,
domainService: domainService,
messageService: messageService,
currentUserAccount: {data: {firstName: 'John'}},
unreadMessagesCount: 0,
latestMessages: []
});
httpBackend = $httpBackend;
//TODO: do I need all those expectations?
httpBackend.whenGET('/api/utils/signup-roles').respond({});
httpBackend.whenGET('/api/utils/parents-needs').respond({});
httpBackend.whenGET('/api/utils/childcare-worker-types').respond({});
httpBackend.whenGET('/api/utils/childcare-types').respond({});
httpBackend.whenGET('/api/utils/all-day-to-time-slots').respond({});
httpBackend.whenGET('/api/utils/regular-day-to-time-slots').respond({});
httpBackend.whenGET('/info').respond({build: {version: '1.0'}});
httpBackend.whenGET(/app.+/).respond({});
httpBackend.whenGET('/api/utils/current-useraccount').respond({id: 42, firstName: 'Pedro'});
}));
it('should handle user account updated', function () {
scope.$emit('useraccount:updated');
httpBackend.flush();
expect(scope.currentUserAccount.firstName).toEqual('Pedro');
});
});
请注意,我现在拨打flush()
。
上面的测试有效,但不是很干净,因为我需要为httpBackend提供所有出色的期望......
我猜这是另一个问题。