Angular ui router unit testing (states to urls)
Been having this issue as well, and finally figured out how to do it.
Here is a sample state:
angular.module('myApp', ['ui.router']).config(['$stateProvider', function($stateProvider) { $stateProvider.state('myState', { url: '/state/:id', templateUrl: 'template.html', controller: 'MyCtrl', resolve: { data: ['myService', function(service) { return service.findAll(); }] } });}]);
The unit test below will cover testing the URL w/ params, and executing the resolves which inject its own dependencies:
describe('myApp/myState', function() { var $rootScope, $state, $injector, myServiceMock, state = 'myState'; beforeEach(function() { module('myApp', function($provide) { $provide.value('myService', myServiceMock = {}); }); inject(function(_$rootScope_, _$state_, _$injector_, $templateCache) { $rootScope = _$rootScope_; $state = _$state_; $injector = _$injector_; // We need add the template entry into the templateCache if we ever // specify a templateUrl $templateCache.put('template.html', ''); }) }); it('should respond to URL', function() { expect($state.href(state, { id: 1 })).toEqual('#/state/1'); }); it('should resolve data', function() { myServiceMock.findAll = jasmine.createSpy('findAll').and.returnValue('findAll'); // earlier than jasmine 2.0, replace "and.returnValue" with "andReturn" $state.go(state); $rootScope.$digest(); expect($state.current.name).toBe(state); // Call invoke to inject dependencies and run function expect($injector.invoke($state.current.resolve.data)).toBe('findAll'); });});
If you want to check only the current state's name it's easier to use $state.transitionTo('splash')
it('should transition to splash', inject(function($state,$rootScope){ $state.transitionTo('splash'); $rootScope.$apply(); expect($state.current.name).toBe('splash');}));
I realize this is slightly off topic, but I came here from Google looking for a simple way to test a route's template, controller, and URL.
$state.get('stateName')
will give you
{ url: '...', templateUrl: '...', controller: '...', name: 'stateName', resolve: { foo: function () {} }}
in your tests.
So your tests could look something like this:
var state;beforeEach(inject(function ($state) { state = $state.get('otherwise');}));it('matches a wild card', function () { expect(state.url).toEqual('/path/to/page');});it('renders the 404 page', function () { expect(state.templateUrl).toEqual('views/errors/404.html');});it('uses the right controller', function () { expect(state.controller).toEqual(...);});it('resolves the right thing', function () { expect(state.resolve.foo()).toEqual(...);});// etc