Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

$event.stopPropogation is not a function error in Angularjs Unit Test

I am trying to unit test a function that is bound to the ngClick directive. It looks something like this for now as we've just started on this project and before I get to far I want some test coverage:

vm.open = function($event) {
            $event.preventDefault();
            $event.stopPropagation();
            vm.opened = true;   
        };

I unit test like this:

describe('Unit: simpleSearchController', function(){
//include main module
beforeEach(module('myApp'));
var ctrl, scope, event ;
// inject the $controller and $rootScope services
// in the beforeEach block
beforeEach(inject(function($controller, $rootScope){
    // Create a new scope that's a child of the $rootScope
    scope = $rootScope.$new();
    // Create the controller and alias access using controllerAs
    ctrl = $controller('simpleSearchController as vm', {
        $scope: scope
    });
}));
// unit tests
it('should set vm.opened to true', function(){
    event = scope.$broadcast("click");
    expect(event).toBeDefined();
    scope.vm.open(event);
    expect(event.defaultPrevented).toBeTruthy();
    expect(scope.vm.opened).toBeTruthy();
});
});

When Karma runs the test I get this error:

TypeError: $event.stopPropagation is not a function. 

Any ideas?

like image 263
John Stewart Avatar asked Oct 22 '14 16:10

John Stewart


1 Answers

Your issue is that there is no stopPropagation method on the $broadcasted event. broadcast propagates down and stopPropagation (available in $emit) is used to prevent further propagation upwards. So you have 2 options.

Either use $emit

  it('should set vm.opened to true', function(){
        event = scope.$emit("click");
        expect(event).toBeDefined();
        scope.vm.open(event);
        expect(event.defaultPrevented).toBeTruthy();
        expect(scope.vm.opened).toBeTruthy();
  });

Or just create a mock object for event.

  it('should set vm.opened to true', function(){
            event = jasmine.createSpyObj('event', ['preventDefault', 'stopPropagation']);
            scope.vm.open(event);
            expect(event.preventDefault).toHaveBeenCalled();
            expect(scope.vm.opened).toBeTruthy();
      });

Also note that you really do not need to test expect(event.defaultPrevented).toBeTruthy(); or expect(event).toBeDefined(); because this is core angular functionality when preventDefault is called and it has already been tested.

like image 194
PSL Avatar answered Sep 21 '22 18:09

PSL