chromaloop
chromaloop

Reputation: 222

Testing ui.router $stateChangeSuccess

I have a simple function in my main controller that updates $scope.loading based on ui.router's $stateChangeStart and $stateChangeSuccess events.

$scope.$on('$stateChangeStart', function(event, toState) {
  if (toState.resolve) {
    $scope.loading = true;
  }
});
$scope.$on('$stateChangeSuccess', function(event, toState) {
  if (toState.resolve) {
    $scope.loading = false;
  }
});

This works great until I try to unit test. I can't find a way to trigger the $stateChangeSuccess event.

My Jasmine unit test looks something like this:

it('should set $scope.loading to true', function () {
    expect(scope.loading).toBe(false);
    $state.go('home');
    expect(scope.loading).toBe(true);
    scope.$digest();
    expect(scope.loading).toBe(false);
});

The test fails because $stateChangeSuccess never fires. Any ideas would be much appreciated.

Upvotes: 4

Views: 3892

Answers (1)

Steve Rogers
Steve Rogers

Reputation: 1123

This currently works for me.

You simply need to $broadcast the event. Read below for a bit of pseudocode. I hope this helps you.

// Note: this is pseudocode

// controller
// assumes you have your usual setup to support this controller.
// assumes this controller is attached to a component or angular controller.

function myController() {
  var vm = this;

  vm.isHappy = false;

  $scope.$on('$stateChangeSuccess', function(event, toState) {
    if (toState.name === 'myState') {
      vm.isHappy = true;
    }
  });
}

// test
// assumes several things
//    * ctrl is the currently mocked controller
//    * has all the necessary setup & injections (such as $rootScope).
//    * testing framework is Jasmine

describe('What happens when I go to my happy place?', function() {
  it('should be visible to all that I am happy.', function() {
    expect(ctrl.isHappy).toBeFalsy();

    $rootScope.$broadcast('$stateChangeSuccess', {
      'name': 'myState'
    });
    // or $scope.$broadcast

    expect(ctrl.isHappy).toBeTruthy();
  }
});

Upvotes: 1

Related Questions