Pergunta

I could not find any other question/answer that met my needs, so here it is:

In an AngularJS (1.2.14) controller, I have an event listener that executes an ajax call to fetch some data when an event ('fetchData') is heard. After the fetch is successful, an event (called 'fetchSuccess') is broadcasted, that a directive is listening for (though that part is irrelevant).

$scope.$on('fetchData', function () {
            $scope
                .submitSearch()
                .then(function (results) {
                    $scope.$broadcast('fetchSuccess');
                }, function () {
                    $scope.$broadcast('fetchError');
                });
        });

So, in my test I want to do something like this (assume that 'this.scope' is a new $scope object on the controller in the test suite):

it('should broadcast "fetchSuccess"', inject(function ($rootScope) {
        var scope = this.scope,
            spy = chai.spy(scope, '$broadcast');

        // trigger the $broadcast event that calls the fetch method
        scope.$broadcast('fetchData');

        $rootScope.$apply();

        expect(scope.$broadcast).to.be.called.with('fetchSuccess');
    }));

But I am not clear on how to listen for the $broadcast event in an assertion. I keep getting this error: AssertionError: expected function (name, args) {...}

Just to be clear, my issue is not with the functionality of the event broadcaster or the listeners during runtime; the application works as expected. The problem is with listening to the events in the test suite.

Note that the above code is just the necessary snippet that is needed for this question. In my application, there are other variables/methods that get set/called and those things test out correctly. Meaning that if I test to see if the actual fetching method gets called, or if a particular variable is being set appropriately, those tests pass.

I have tried mixing and matching the scope variables and even listening for the $broadcast via scope.$on('fetchSuccess', fn) but nothing seems to work. The fetchSuccess event doesn't seem to get emitted, or I'm not listening for it properly.

Thanks in advance, Ryan.

Foi útil?

Solução

So, I have found the answer to my question and it was all my fault. Though I did have to modify the way the test was written, the core problem as simple as listening for the wrong event!

But, for those that want to know what my test looked like, here is the final test (rootscope is being set to $rootScope elsewhere):

it('should broadcast a "fetchSuccess" event', function (done) {
    var eventEmitted = false;
    this.scope.$on('fetchSuccess', function () {
            eventEmitted = true;
            done();
        });

        this.scope.$broadcast('fetchData');

    rootscope.$apply();

    eventEmitted.should.be.true;
});

There was no need to spy on the $broadcast event, the AngularJS $on listener is sufficient.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top