I have a sample route like this :
angular
.module('appRouter',['ui.router'])
.config(function($stateProvider,$urlRouterProvider){
$stateProvider
.....
.....
.state('settings.account',{
url:'/account',
templateUrl:'templates/account.html',
controller:function(resolveData){
console.log(resolveData);
},
resolve:{
resolveData : function($http){
var root = 'https://jsonplaceholder.typicode.com';
return $http.get(root+'/posts/1').then(function(response){
return response.data;
});
}
}
});
.....
It is just a test URL where I can get sample JSON data online
https://jsonplaceholder.typicode.com/posts/1
I wanted to test the state.
beforeEach(function(){
module('appRouter');
});
beforeEach(inject(function(_$rootScope_,_$injector_,_$state_,_$httpBackend_,$templateCache){
$rootScope = _$rootScope_;
$state = _$state_;
$injector = _$injector_;
$httpBackend = _$httpBackend_;
$templateCache.put('templates/account.html','');
}));
it('should resolve "resolveData"',function(){
const state = $state.get('settings.account');
const resolveFn = state.resolve.resolveData;
$httpBackend.whenGET('https://jsonplaceholder.typicode.com/posts/1').respond(function(){
return [
200,{
"userId": 1,
"id": 1,
"title": "...",
"body": "..."
}]
});
$httpBackend.expectGET('https://jsonplaceholder.typicode.com/posts/1');
$injector.invoke(resolveFn);
$httpBackend.flush();
expect($injector.annotate(resolveFn)).toEqual(['$http']);
console.log(angular.mock.dump($scope));
expect($scope.resolveData).toEqual({
"userId": 1,
"id": 1,
"title": "...",
"body": "..."
});
But this fails. Saying
1) should resolve "resolveData"
UI Routerer Config For Account
Expected undefined to equal Object({ userId: 1, id: 1, title: '...', body: '...' }).
at Object.<anonymous> (test/controllers/main-controller-spec.js:114:36)
What am I doing wrong ?
UPDATE
console.log(angular.mock.dump($scope));
gives the following
Please help.
Original Error:
should resolve "resolveData"
UI Routerer Config For Account
TypeError: Cannot read property 'get' of undefined
at resolveData (app/appRouter.js:25:41)
at Object.<anonymous> (test/controllers/main-controller-spec.js:97:9)
What am I doing wrong?
You are calling resolveFn()
in your unit test. The function was defined as requiring the $http
service, and that call does not pass the $http
service (as fingerpich mentioned).
To correct this, allow angular to handle the dependency injection by using $injector.invoke(resolveFn)
.
See this in action with a plunk. Note the test does fail for a different reason. But, (if I understand the rules correctly) that is a different issue should be answered with a different question (if you need more help).
A side note: When the site (not the unit test) is opened in a browser, I would expect it to work, because angular injects the $http
dependency into the function assigned to resolveData
.
Look at answer that also references the blog mentioned by fingerpich.
Here is a blog I found helpful when learning about unit testing AngularJS.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With