RVR
RVR

Reputation: 97

Karma error - Expected undefined to be defined

I want to unit test my controller. I started with basic test assertions of expect API. But I am facing challenge in mocking scope methods inside a conditional check. I am getting an undefined error since it is not available under scope, only the global logout() method is available.

I tried mocking the localStorageService using spyOn as true to satisfy the condition, but that's still of no help. Any solution will be of great help to get me kickstarted.

Controller:

angular.module('app').controller('sampleCtrl',

        function($scope, $state, $http, $rootScope, localStorageService) {

            if (!(localStorageService.get('isAuthenticated'))) {

                 $state.go('home');

            }
            if (localStorageService.get('isAuthenticated') === true) {

                 //http post calls made here to perform certain operation on page load

                 $scope.someMethod = function(){

                     //do something

                  }

            }

            $scope.logOut = function() {

               localStorageService.set('property', '');

               localStorageService.set('isAuthenticated', false);

               $state.go('home');

          };
 });

Karma:

'use strict';

describe('Controller: sampleCtrl', function() {

    /** to load the controller's module */
    beforeEach(module('app'));

    var sampleCtrl,scope,httpBackend,deferred,rootScope;

    beforeEach(inject(function ($controller,_$rootScope_,$httpBackend,$q) {

        var store = {};
        scope= _$rootScope_.$new(); // creates a new child scope of $rootScope for each test case
        rootScope           = _$rootScope_;
        localStorageService = _localStorageService_;
        httpBackend         = $httpBackend;

        httpBackend.whenGET(/\.html$/).respond(''); 

        spyOn(localStorageService, 'set').and.callFake(function (key,val) {
            store[key]=val;
         });

        spyOn(localStorageService, 'get').and.callFake(function(key) {
            return store[key];
         });

        sampleCtrl = $controller('sampleCtrl',{
            _$rootScope_:rootScope,
             $scope:scope,
             $httpBackend:httpBackend,
            _localStorageService_:localStorageService
            // add mocks here
        });

        localStorageService.set('isAuthenticated',true);

    }));

    /**ensures $httpBackend doesn’t have any outstanding expectations or requests after each test*/
    afterEach(function() {
        httpBackend.verifyNoOutstandingExpectation(); 
        httpBackend.verifyNoOutstandingRequest();     
    }); 


    it('sampleCtrl to be defined:',function(){

        httpBackend.flush(); 
        expect(sampleCtrl).toBeDefined();

    });

    // failing test case - scope.someMethod not available in scope
    it('is to ensure only authenticated user can access the state methods',function(){
            localStorageService.get('isAuthenticated');
            httpBackend.flush();
            expect(scope.someMethod).toBeDefined(); 
    });


});

Upvotes: 2

Views: 8333

Answers (1)

min che
min che

Reputation: 158

I've managed to get it work. The problem was that localStorageService did not have isAuthenticated set to true on starting the controller. Place setting it to true before calling the controller.

Upvotes: 1

Related Questions