3

Hello Everyone I am struggling at testing a $.on function and I am looking for any suggestions or help on this:

controller

  $scope.$on("sampleFilesSelected", function(event, args) {
                $scope.sampleFiles = args.newSampleFiles;
            }); 

spec

describe('Testing a $.on', function() {
  var $scope = null;
  var ctrl = null;


  beforeEach(module('test'));

  it('should invoke myEvent when "myEvent" broadcasted', inject(function($rootScope, $controller) {
    $scope = $rootScope.$new();

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

    $scope.$broadcast('myEvent');
    expect($scope.sampleFilesSelected).toBe(true);
  }));
});

error

TypeError: Unable to get property 'newSampleFiles' of undefined or null reference
        undefined

3 Answers 3

3

You should pass a value to your event, call a $digest before your assertion :

$scope.$broadcast('myEvent', { 'newSampleFiles' : true } );
$scope.$digest();
expect($scope.sampleFilesSelected).toBe(true);
Sign up to request clarification or add additional context in comments.

Comments

1

this code ...

$scope.$broadcast('myEvent');

is not passing any args and so args.newSampleFiles throws an error because args is undefined

you need to pass args - how you do that I don't know

However, I would say ... unit testing is used for testing controller code not really for testing event handling. Your example is a bit of an edge case. I would be tempted to test the event handling use E2E testing and protractor.

I would refactor as follows ...

$scope.$on("sampleFilesSelected", function(event, args) {
                $scope.sampleFiles = args.newSampleFiles;
            });

would become ...

$scope.myFunction = function(event, args) {
   $scope.sampleFiles = args.newSampleFiles;
}

$scope.$on("sampleFilesSelected", $scope.myFunction);

and i would unit test $scope.myFunction. And leave the testing of $scope.$on to E2E protractor testing.

Hope that helps

2 Comments

I will agree this is a better way to write it.
its not meant to be a better way to write it - its to allow it to be unit tested without relying on events firing - the events themselves can be tested in protractor
1

You're making three mistakes, first one being is that you're listening/subscribing to a event named sampleFilesSelected in your controller but in your test, you're broadcasting to anyone that's listening to an event called myEvent?

Secondly, once above is fixed, you should run $scope.$digest() cycle after you trigger an event and then you can follow it up with your expect(...).

Third, as mentioned by others, you should pass the data as second arg when $broadcast ...ing!

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.