3

I'm having a lot of trouble getting this simple test working.

I've got an $scope.$on listener in a controller that I want to test. I just want to make certain it's called after a broadcast event.

To do this, I thought the following code would work:

describe("Testing the parent controller: ", function() {
    var scope, ctrl;

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

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

            ctrl = $controller('parent-ctrl', {
                $scope: scope,
            });
        });
    });


    it ("should trigger broadcast when current page updates", function() {
        spyOn(scope, "$on");
        scope.$broadcast("myEvent", 999);
        expect(scope.$on).toHaveBeenCalled();
    });
});

It doesn't (Expected spy $on to have been called.). I've dug through numerous examples:

and learned a lot, but for some reason I'm just not making some critical connection.

I have noticed that the $on handler does respond post-assertion, which is unhelpful. I've tried scope.$apply() and .andCallThrough() in various configurations but nothing seems to work.

How is this done?

Community
  • 1
  • 1
Ben
  • 54,723
  • 49
  • 178
  • 224

1 Answers1

8

When the event is broadcasted it is the listener function that was registered with $on that is executed, not the $on function itself.

Your current test would work for code like this, which is probably not what you have:

$scope.$on('myEvent', function () {
    $scope.$on('whatever', someFn);
});

What you should be testing is whatever your registered listener function is doing.

So if you for example have:

$scope.$on('myEvent', function() {
  myFactory.doSomething();
});

Test it like this:

spyOn(myFactory, "doSomething");
scope.$broadcast("myEvent");

expect(myFactory.doSomething).toHaveBeenCalled();
tasseKATT
  • 38,470
  • 8
  • 84
  • 65