user1859465
user1859465

Reputation: 883

Mocking $state change in AngularJS controller

Main module being injected with everything;

require('./dashboard');
module.exports = angular.module('college', ['college.dashboard'])

    .config(function ($stateProvider) {
        $stateProvider
            .state('college.list', {
                url: '/college',
                templateUrl: '/dashboard/dashboard.html',
                controller: 'DashboardCtrl',
                authenticate: true
            });
    })
    .factory('ProjectFactory', require('./services/college.service'));        

College Index, which makes the dashboard controller available;

module.exports = angular.module('college.dashboard', 
  [])
    .controller('DashboardCtrl', require('./dashboard.controller.js'));

The college controller exposes the following method;

    module.exports = function($scope, $rootScope, $state) {

         $scope.openCollege = function(id) {       
            $rootScope.currentCollege = id;
            $state.go('college.main', {currentCollege: id});
        };
   };

The following error is thrown when the unit test calls

scope.openCollege (2);

Error:

 Error: Could not resolve 'college.main' from state ''

Creating state;

beforeEach(inject(function ($rootScope, $state, $location, $controller) {
        scope = $rootScope.$new();
        location = $location;
        rootScope = $rootScope;
        $rootScope.currentCollege = {};// Empty by default
        state = $state;            

        $controller('DashboardCtrl', {
            $scope: scope,
            $state: state,
            $location: location
        });

    }));

Some of the spec test code;

 expect(state.current.name).to.equal('');
 scope.openCollege(2);

I need to figure out how to handle/mock $state.go during the Karma unit testing so that state knows about college.main.

Any help is appreciated.

J

Upvotes: 2

Views: 4254

Answers (2)

user1859465
user1859465

Reputation: 883

Here is how I got it working;

I added the following to the spec test;

// Globally defined
var stateSpy;

// within the beforeEach
stateSpy = sinon.stub($state, 'go');

// In the unit test
scope.openCollege (2);
assert(stateSpy.withArgs('college.main', '{currentCollege: 2}').calledOnce);

Note: the $state was not passed to the the controller.

I now have green tests!

Thanks for your help, gave me the idea of how to make this work.

J

Upvotes: 4

Aditya Sethi
Aditya Sethi

Reputation: 10586

You should use

it('should be able to go to person edit state', function () {
    DashboardCtrl();
    scope.openProject('12345');
    scope.$digest();
    expect(state.go).toHaveBeenCalledWith('college.main', { id : '12345' });
});

Upvotes: 2

Related Questions