9

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

enter image description here

Please help.

2
  • I think there was value in the original question you asked (before the edit), with the original error. This new error message should be a new question. They are both two separate problems, that should be handled individually. Commented Feb 2, 2017 at 13:31
  • 2
    i dont understand exactly what are you trying to test here. I mean: tests should examine if your code is doing some logic you expect it to do. But instead (as far as i can see) your test examines if you can get some json from some request. Thats not the purpose of tests. May be it is good purpose of server side tests. Instead i suggest you to call some service inside the "resolve" (just replace the $http call by injecting some service and call one of its methods), now you can test ifs service is called in response of "state.go", and if service called with corrrect params. (Thats my opinion) Commented Feb 3, 2017 at 6:32

2 Answers 2

2
+25

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.

Sign up to request clarification or add additional context in comments.

6 Comments

I tried the same but it did not work out for me. It said Expected undefined to equal Object({ userId: 1, id: 1, title: ... when I expect $scope.resolveData to match the JSON data. What am I doing wrong ?
Do you still receive the error should resolve "resolveData"... TypeError: Cannot read property 'get' of undefined...? If not, your original question should be resolved and the error mentioned in the comment would fall under a new question.
Perhaps a little nudge will help with the new error: add console.log(angular.mock.dump($scope)); prior to the expect statement at the end of the test. After that, checkout how the .then() is used with the $injector.invoke() call here (I included this link in my answer).
console.log(angular.mock.dump($scope)); gives the error . See the updates.
moreover $injector.invoke($state.get('settings.account').resolve['resolveData']) .then(function(res){console.log(res.data);}); gives me undefined. I tried to follow the steps mentioned in the answer you referred to.
|
1
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)

to solve this problem you should pass $http to resolveData function.

resolveFn($http); 

but it's better to write tests like this

2 Comments

Sorry but this says ` ReferenceError: $http is not defined` . Please have a look at it.
I did that. And it failed saying the error I mentioned. How to overcome?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.