How can I test Broadcast event in AngularJS
Asked Answered
L

2

63

I have a controller which emits a broadcast event on the rootscope. I would like to test that the broacast event is fired correctly.

My code in my controller looks like this:

   $scope.$watch("pageIndex", function(){
    if($scope.pageIndex == 4)
    {
      // emit social share
      $rootScope.$broadcast('myEvent');
    }
  });

I have tried to test it with the following code:

    it('Should call myEvent when pageIndex is 4',function(){
    scope.pageIndex = 4;
    scope.$apply();
    expect(rootScope.$on).toHaveBeenCalledWith('myEvent');
});

But it tells me that the code isn't called, which I have manually tested that it does. I have then tried with the following code:

it('Should call myEvent when pageIndex is 4',function(){
    var listener = jasmine.createSpy('listener');
    rootScope.$on('myEvent', listener);
    scope.pageIndex = 4;
    scope.$apply();
    expect(listener).toHaveBeenCalled();
});

But with the same negative result. Is there a way to test that an event is broadcasted?

Lemaceon answered 26/5, 2013 at 8:32 Comment(0)
P
117

Assuming you're using Jasmine, the following is working great for me.

... other unit test setup code ...

var rootScope;
beforeEach(inject(function($injector) {
    rootScope = $injector.get('$rootScope');
    spyOn(rootScope, '$broadcast');
}));

describe("my tests", function() {
    it("should broadcast something", function() {
        expect(rootScope.$broadcast).toHaveBeenCalledWith('myEvent');
    });
});

If you're broadcasting a message and attaching objects to it, you can even test that the objects match expectations

someObj = { ... something ... };
expect(rootScope.$broadcast).toHaveBeenCalledWith('someEvent', someObj);
Pyx answered 21/6, 2013 at 3:30 Comment(7)
@Mike: Any way you can show an example of this solution with Mocha/Chai?Bully
@RyanConaway - for Chai it looks like you'll need a spy plugin such as github.com/chaijs/chai-spies . For Mocha, check out sinonjs.org. The documentation for both of those are pretty clear on how you'd achieve this solution with either library.Pyx
How does one test that multiple calls with different arguments?Tamathatamaulipas
@IntegrityFirst - just create more expectations (preferably in their own isolated tests)Pyx
how can we do the same with mocha-chai? I am getting error as spyOn not defined.Fulgurating
@mayank see my answer to Ryan Conaway above.Pyx
If you are broadcasting a message and attaching a objects, and if you don't want to specify the exact object: expect(rootScope.$broadcast).toHaveBeenCalledWith('someEvent', jasmine.anything());Trivalent
G
12

Here's how its done with mochaJs, with sinon for mocks and chai for expectations.

describe("broadcast test", function() {
  beforeEach(inject(function($rootScope){
   sinon.spy($rootScope, "$broadcast")
   scope.foo() //this broadcasts the event. $rootScope.$broadcast("testEvent")
 }))

it("broadcasts the event", inject(function($rootScope){
 expect($rootScope.$broadcast.calledWith("testEvent")).to.be.true
}))

})
Grecoroman answered 13/1, 2016 at 16:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.