1

I have a service with a function to use $http with promise. And i want create a unit-testing with jasmine.

account.service('AccountService', ['$q', '$http', function ($q, $http) {
    this.getServerDataForUrl = function (url) {
         var def = $q.defer();
         $http.get(url)
              .success(function (data) {
                   if (data) {
                      def.resolve(data);
                   } else {
                      def.reject();
                   }
               })
               .error(function (error) {
                   if (data) {
                      def.resolve(data);
                   } else {
                      def.resolve();
                   }
                });
         return def.promise;
    };
}]);

UPDATE: Change something code when callback.
I've search about it but it not give me exactly function like this. Anyone give me some example to create unit-testing about it. I think this function is simple. Thanks.

4
  • 1
    The only thing that can be tested here is whether a request was made to the specific url. There are numerous example of testing http service online. Commented Jul 27, 2015 at 7:18
  • 1
    Actually what you are doing in your code is redundant. $http itself returns a promise. Why do you need to have such code? Commented Jul 27, 2015 at 7:19
  • The forgotten promise anti-pattern Commented Jul 27, 2015 at 7:41
  • Hi @Chandermani. It's not my code. My mission is write unit-testing for it :) Commented Jul 27, 2015 at 7:49

3 Answers 3

3

You should really just

return $http.get(url);

There's no point in wrapping a promise in a deferred object.

This is the only testable thing I can think of

describe('AccountService test', function() {
    var $http;

    beforeEach(module('accountModule', function($provide) {
        $provide.value('$http', $http = jasmine.createSpyObj('$http', ['get']));

        // if you aren't going to change the code to not wrap
        // the $http promise, add this

        var httpPromise = {
            success: function(cb) {
                cb('success');
                return httpPromise;
            },
            error: function(cb) {
                cb('error');
                return httpPromise;
            }
        };

        $http.get.and.returnValue(httpPromise);
    }));

    it('proxies through to $http.get', inject(AccountService) {
        AccountService.getServerDataForUrl('url');
        expect($http.get).toHaveBeenCalledWith('url');
    }));
});
Sign up to request clarification or add additional context in comments.

3 Comments

I run your code. But it get message: "TypeError: Cannot read property 'success' of undefined". What can i do with your code now?
@PhamMinhTan I assumed you'd update the code to not wrap the $http promise in a deferred object. I've updated my answer
Great! Your code is run properly.Thank you. Can you give me some tutorial and example to write unit-testing. Because, i want to write it. Anyway. Thank you very much.
1

in spec create an variable which holds the reference of your AccountService instance and use angular inject function to get it instantiated.

now you can use jasmine spys for testing functions or use marchers to test service public members.

    var AccountSvs = undefined;
    beforeEach(inject(function (AccountService) {
    AccountSvs = AccountService;
    }));

    it('..', function(){
      expect(AccountSvs.getServerDataForUrl).toBeDefined();
AccountSvs.getServerDataForUrl().then(/*success callback*/function(){}, /*error callback*/function(){}, /*notify callback*/function(){});
    });

Comments

0

its not a big deal to handle promise in unit testing since its async you need to the following.

describe('AccountService',function(){
 var service = null;
    beforeEach(inject(function (AccountService) {
    service = AccountService;
    }));

    it('checkService here', function(done){
         expect(service .getServerDataForUrl).toBeDefined();
        service .getServerDataForUrl().then(function(resp){
         expect(resp.data).not.ToBeNull();   
          done();

     });
});

resp.data will contain your actual data returned from service.

Comments

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.