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?

2 Answers 2

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);
Sign up to request clarification or add additional context in comments.

7 Comments

@Mike: Any way you can show an example of this solution with Mocha/Chai?
@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.
How does one test that multiple calls with different arguments?
@IntegrityFirst - just create more expectations (preferably in their own isolated tests)
how can we do the same with mocha-chai? I am getting error as spyOn not defined.
|
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
}))

})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.