Angular ui router unit testing (states to urls) Angular ui router unit testing (states to urls) angularjs angularjs

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