How can I trigger `$ on` events in AngularJS Karma unit tests?

I am trying to run the $scope.$on() method $scope.$on() controller that fires when I have a $rootScope.broadcast() event. I found this question helpful: How to check events in angular? but I am still having trouble detecting an event being broadcast from $rootScope up to the $scope controller.

So far, I have been able to verify that the $broadcast method is called on the corresponding $rootScope , but not that the $on method is called on the corresponding $scope when $broadcast is called on $rootScope .

I tried $rootScope.$broadcast directly in my test, but my spy is not dialing an event.

This is my controller:

 angular.module('app.admin.controllers.notes', []) .controller('NotesCtrl', function($scope) { $scope.$on('resource-loaded', function(event, resource) { // I want to test this $scope.parentType = resource.type; $scope.parentId = resource.id; }); }); 

This is my test:

 describe('The notes controller', function() { beforeEach(module('app.admin.controllers.notes')); var scope, rootScope, NotesCtrl; beforeEach(inject(function($controller, $injector, $rootScope) { rootScope = $rootScope; scope = $rootScope.$new(); // I've tried this with and without $new() NotesCtrl = $controller('NotesCtrl', {$scope: scope}); // I've tried explicitly defining $rootScope here })); it('should respond to the `resource-loaded` event', function() { spyOn(scope, '$on'); rootScope.$broadcast('resource-loaded'); // This is what I expect to trigger the `$on` method expect(scope.$on).toHaveBeenCalled(); }); }); 

And here is plunkr . I included passing the test of the $broadcast method for reference, mainly because I configured the tests in the same way.

I read quite a few questions related to event testing in AngularJS, and this always seems to be a problem. I heard that in Karma unit testing, $rootScope and $scope are the same thing, but I'm not quite sure what implication is. I tried to define $rootScope and $scope as the same object, and also explicitly insert $rootScope in NotesCtrl during testing, but nothing makes my test green.

How can I run the $on method in my NotesCtrl for this test?

+6
source share
3 answers

What doesn't work is that you are following the $on function. It works great when it does not put it off: http://plnkr.co/edit/hNEj7MmDDKJcJ7b298OB?p=info . And the reason is actually simple. When the event is brodcasted, what is called is not a function of $on() . The callback function that was previously passed as the argument to $on() is called: the listener.

Note that by snooping on the $ on function, you are not testing your code here. All you are trying to verify is that when you broadcast the event event, its child areas will receive it. So you are testing AngularJS itself.

+11
source

Try using

 $rootScope.$emit('resource-loaded'); 

Works well in my tests.

+1
source

@ kirill.buga

Using $ broadcast is correct, not $ emit, because:

https://docs.angularjs.org/api/ng/type/$rootScope.Scope Sends the event name up the region hierarchy, notifying registered listeners of $ rootScope.Scope.

Problem @ ben-harold is trying to peek at $ instead of the result of the code at $ on.

+1
source

Source: https://habr.com/ru/post/977158/


All Articles