Angular empty state name when checking routing with jasmine
Like many people, I am new to testing Angular with Jasmine and I am trying my best to get it right. I am using ui-router to do my routing and right now the problem I am having is that the $ state.current.name in the test is an empty string and I have no idea why this is happening what.
This is the code in my routing module:
var cacRouteViewMod = angular.module('cacRouteViewMod', ['ui.router', 'cacLib']);
cacRouteViewMod.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('countries', {
url: '/countries',
templateUrl: 'countries/countries.html',
controller: 'countriesCtrl',
resolve : {
countries: ["getCountry", function(getCountry) {
return getCountry();
}]
}
});
}]);
and the test I wrote is this:
describe('cac_app_views (routing)', function() {
var $rootScope,
$state,
$injector,
getCountryMock,
state = 'countries';
beforeEach(function() {
module('cacRouteViewMod', function($provide, $urlRouterProvider) {
$urlRouterProvider.deferIntercept();
$provide.value('getCountry', getCountryMock = {});
});
inject(function(_$rootScope_, _$state_, _$injector_, $templateCache) {
$rootScope = _$rootScope_;
$state = _$state_;
$injector = _$injector_;
$templateCache.put('countries/countries.html', '');
})
});
// Test 1
it('should respond to URL', function() {
expect($state.href(state)).toEqual('#/countries');
});
// Test 2
it('should resolve getCountry', function() {
getCountryMock = jasmine.createSpy('getCountry').and.returnValue('nanana');
$rootScope.$apply(function() {
$state.go('countries');
});
expect($state.current.name).toBe('countries');
expect($injector.invoke($state.current.resolve.countries)).toBe('nanana');
});
});
Test 1 is good, but problem 2 is a problem. The test fails because it expected "to be" countries.
When I write $ state.current to the console it gives
Object {name: "", url: "^", views: null, abstract: true}
I'm getting pretty desperate at this point. Can anyone help me understand / solve this problem?
source to share
I solved it this way:
After reading similar postoverflow columns, I posted a listener for $stateChangeError
and it was fired. I dumped the data error
and saw that it was a typeError: getCountry is not a function
. This made it $state
not update and hence still contains the original (empty) one $state
.
I fixed $provide.value
like this:
$provide.value('getCountry', getCountryMock = function() {return 'nanana';});
which says "When called getCountry
, instead getCountryMock
specify getCountryMock
which is a function that returns a string 'nanana'
.
All tests now work the way I want them to.
Note. I found that the line of code was getCountryMock = jasmine.createSpy.....
out of date and my other change was $provide.value()
, so I commented that out.
source to share
As per the documentation $state.go
, a promise is returned.
You should use a function done()
from Jasmine to test this code: http://ng-learn.org/2014/08/Testing_Promises_with_Jasmine/
source to share