cusejuice
cusejuice

Reputation: 10671

Unit testing controller with injected service

What is the best way to go about unit testing the following controller? I'm having trouble properly injecting AuthService into my controller. I've seen so many different ways to do it and I'm not really sure what the best practice is - i.e. mocks vs spies?

I have a simple service like this:

   angular.module('users')
      .factory('AuthService', ['$http', '$window',
        function($http, $window) {
          var authService = {};

          authService.login = function(creds) {
            return $http.post('/auth', creds)
              .then(function(res) {
                $window.localStorage.exampleToken = res.data.returned_token;
                return res;
              });
          };

          authService.isLoggedIn = function() {
            if($window.localStorage.exampleToken) {
              return true;
            } else {
              return false;
            }
          };

          authService.clear = function() {
            delete $window.localStorage.exampleToken;
          };

          return authService;
        }]);

My controller:

   angular.module('users')
      .controller('ExampleCtrl', ['AuthService', 
        function(AuthService) {
          var vm = this;

          vm.isLoggedIn = AuthService.isLoggedIn();
        }]);

My unfinished test:

 describe('ExampleCtrl', function() {
      beforeEach(module('users'));

      var ctrl;

      beforeEach(inject(function($controller) {
        ctrl = $controller('ExampleCtrl', {});
      }));

      describe('when logged in', function() {
        beforeEach(function() {
          // how do i mock the isLoggedIn function to 
          // return true
        });

        it('should return true', function() {
          expect(ctrl.isLoggedIn).toBe(true);
        });

      });

      describe('when not logged in', function() {
        beforeEach(function() {
          // how do i mock the isLoggedIn function to 
          // return false
        });

        it('should return false', function() {
          expect(ctrl.isLoggedIn).toBe(false);
        });

      });

    });

Upvotes: 1

Views: 143

Answers (1)

Mik378
Mik378

Reputation: 22171

You can merely use the callFake function of Jasmine:

By chaining the spy with and.callFake, all calls to the spy will delegate to the supplied function.

var AuthService; //so that you can have a reference within all your test file
beforeEach(function() {
     inject(function(_AuthService_) {
       AuthService = _AuthService_;
     });
     spyOn(AuthService, 'isLoggedIn').and.callFake(function() {
          return true;
     });
});

Upvotes: 1

Related Questions