1

How do I test a scope variable that gets changed by an event?

This is the bit of code I want to test:

$rootScope.$on('someEvent', function(event, option) {
  $scope.option = option;
});

I'm trying to do

describe("`someEvent`", function() {
  var option = 'Title',

  beforeEach(inject(function($injector) {
    $scope.$emit('someEvent', option);
  }));

  it("updates option", function() {
    expect($scope.option).toBe(option);
  });
});

I've also tried with $timeout

describe("`someEvent`", function() {
  var option = 'Title',
    $timeout;

  beforeEach(inject(function($injector) {
    $timeout = $injector.get('$timeout');
    $timeout(function() {
      $scope.$emit('someEvent', option);
    });
    $timeout.flush();
  }));

  it("updates option", function() {
    expect($scope.option).toBe(option);
  });
});

and

describe("`someEvent`", function() {
  var option = 'Title';

  beforeEach(inject(function($injector) {
    var $rootScope = $injector.get('$rootScope');

    $rootScope.$broadcast('someEvent', option);
  }));

  it("updates option", function() {
    expect($scope.option).toBe(option);
  });
});

But they all fail with the message Expected undefined to be 'Title'.

I'm guessing because it's async, and I need some other syntax for it. I'm using jasmine.

Any ideas?


Edit: Updated with more attempts


Fixed: It was because the describe block was declared in the wrong area, where $scope had not been set up. Pretty much the same as How do I unit test $scope.$emit changing a scope variable in angularjs?, so closing it.

Community
  • 1
  • 1
zlog
  • 3,316
  • 4
  • 42
  • 82
  • See http://stackoverflow.com/questions/15272414/what-is-the-best-approach-to-test-events-in-angular/ – dnc253 Oct 01 '13 at 16:26
  • Thanks, I have seen that before though. I have already tested that the event is emitted. What I want to test here is that the scope variable (`$scope.option`) is changed. – zlog Oct 01 '13 at 16:30
  • There are two parts to that answer. The first part is testing that the event is emitted. The second part (the part you want) is about testing what is in the `$on`. Basically you just want to broadcast the event from the `$rootScope` and then your listener will run, and then you can run your expects. – dnc253 Oct 01 '13 at 16:34
  • I've updated my question with my attempt using `$rootScope.$broadcast`, but that doesn't work either. Is that what you meant? – zlog Oct 01 '13 at 16:45
  • It looks like you're using $rootScope and $scope interchangeably... is it possible that your listener is setting the value on a child scope? – David Bennett Oct 01 '13 at 16:46
  • 1
    In the examples above, you don't show where `$scope` is coming from. Depending on where that gets set, the listener may not be registered when you do the `$rootScope.$broadcast`. Make sure the `$scope.$on` has had a chance to run before broadcasting the event. In tests I have like this, I put the `$broadcast` in the `it` and not the `beforeEach`. – dnc253 Oct 01 '13 at 16:57
  • @dnc253 - you were on the right track. Stupid me, I put my describe block as a sibling without setting up `$scope`. Putting it in a describe block that sets up `$scope` runs fine, as per your other SO response (even in the `beforeEach` block). Thanks a bunch! – zlog Oct 01 '13 at 17:18

0 Answers0