Oam Psy
Oam Psy

Reputation: 8663

Unit testing $scope.$on - event not caught

I have a controller with a simple $scope.$on:

app.controller('MyController', function($scope) {
    $scope.$on("myBroadRcvr", function(event, data) {
        $scope.name = data.name;
        $scope.empID = data.empID;
    });
});

I have tried unit testing like this:

describe('MyController', function () {
    var $scope, super_controller;

    beforeEach(function(){
        module('myApp');

        inject(function($rootScope, $controller){
            $scope = $rootScope.$new();
            spyOn($scope, '$on');

            super_controller = $controller('MyController', {$scope: $scope});            
        });
    });

    it('should receive name as test', function (){

        var myData = {name: 'test', empID: 'eg7gg'},
        var sub_scope = $scope.$new();

        sub_scope.$broadcast('myBroadRcvr', myData);

        expect($scope.$on).toHaveBeenCalled();
        expect($scope.name).toBe('test');
    });
});

With the above i get:

Expected undefined to be 'test'.

Upvotes: 1

Views: 395

Answers (1)

doldt
doldt

Reputation: 4506

Your sub_scope is the child of $scope, but $broadcast sends the event downwards the scope hierarchy, so your listener on the parent scope ($scope in this case) can't catch it. You should use $emit instead, as such:

sub_scope.$emit('myBroadRcvr', myData);

See the docs on $broadcast here:

Dispatches an event name downwards to all child scopes (and their children) notifying the registered $rootScope.Scope listeners.

(contrast that with $emit, sending upwards.)


Your code also has a small syntax error: the line var myData = {name: 'test', empID: 'eg7gg'}, should end with a ; instead.

Upvotes: 3

Related Questions