Search code examples
angularjskarma-runnerkarma-jasmineangular-mock

karma test returning validateAmount is not a function


I'm trying to test scope function which will check due amount, but while running the test I'm getting validateAmount is not a function.

app.js

var ManagmentApp = angular.module("ManagemntApp", ['ngRoute', 'angularModalService', 'ng-fusioncharts']);
ManagmentApp.config(['$routeProvider', function ($routeProvider){
     $routeProvider.when('/', {
        templateUrl: 'templates/CandidateForm.html',
        controller: 'cntrlrCandidate'
    }).when('/CandidateList',{
          templateUrl: 'templates/CandidateList.html',
          controller: 'cntrlrCandidateList'
    }).when('/CandidatesProfile', {
        templateUrl: 'templates/CandidateProfiles.html',
        controller: 'cntrlrCandidateProfile'
    }).when('/HostelStatistics', {
        templateUrl: 'templates/HostelStatistics.html',
        controller: 'cntrlHostelStatistics'
    }).when('/:id', {
         templateUrl: 'templates/CandidateForm.html',
         controller: 'cntrlrCandidate'
    });

}]);

cntrlrCandidate.js

ManagmentApp.controller("cntrlrCandidate", ["$scope", "$routeParams", "HostelManagementService", "$filter","HostelManagementIndexDBService", function ($scope, $routeParams, HostelManagementService, $filter,HostelManagementIndexDBService) {

    $scope.validateAmount = function () {
    var vrAmount = $scope.Candidate.Amount;
    var vrTotalAmount = $scope.PerMonthCharge;
    if (+vrAmount < +vrTotalAmount) {
        $scope.IsValidAmount = false;
        $scope.Candidate.DueAmount = (+vrTotalAmount - +vrAmount);

    } else {

        $scope.IsValidAmount = true;
        $scope.Candidate.DueAmount = 0;            
    }
}


}]);

test.js

describe("ManagemntApp ", function() {

beforeEach(module('ManagemntApp'));
 var scope;
var cntrlrCandidate,
$location;

beforeEach(inject(function ($controller,$rootScope){
   scope = $rootScope.$new();
   cntrlrCandidate = function() {
            return $controller('cntrlrCandidate', {
                '$scope': scope
            });
        };;
}));


    it('test amount', function() {

     scope.Candidate={};
     scope.Candidate.Amount=2000;
     scope.validateAmount();
      expect(scope.IsValidAmount).toEqual(true);
    });


});

I couldn't figure out what making notice.

This is the error I'm getting.TestError

Update1:

When I wrote like this the error message is below.

beforeEach(inject(function ($controller,$rootScope){
   scope = $rootScope.$new();
 //  cntrlrCandidate = function() {
            cntrlrCandidate= $controller('cntrlrCandidate', {
                '$scope': scope
            });
       // };;
}));

Please check this error: enter image description here

Update 2:

I tried this way, please correct me if I did anything wrong.

describe("ManagemntApp ", function() {
var HostelManagementIndexDBService,HostelManagementService; 
beforeEach(module('ManagemntApp'));
 var scope;
var cntrlrCandidate,
$location;

beforeEach(inject(function ($controller,$rootScope){
   scope = $rootScope.$new();
 //  cntrlrCandidate = function() {
    HostelManagementService = {}; 
    HostelManagementIndexDBService = {};
    module(function($provide) {
    $provide.value('HostelManagementService', HostelManagementService);
    $provide.value('HostelManagementIndexDBService', HostelManagementIndexDBService);
    });

    cntrlrCandidate= $controller('cntrlrCandidate', {
                '$scope': scope
            });
       // };;
}));


    it('return will pass the Amount', function() {

     scope.Candidate={};
     scope.Candidate.Amount=2000;
     scope.validateAmount();
      expect(scope.IsValidAmount).toEqual(true);
    });


});

Solution

  • cntrlrCandidate = function() {
                return $controller('cntrlrCandidate', {
                    '$scope': scope
                });
            };
    

    You have defined the function cntrlrCandidate but not calling anywhere.

    You need to call it first then you will get your controller;

    Add this line after the cntrlrCandidate defination;

    var ctrlCandidate  =cntrlrCandidate ();
    

    OR

    better if you define like this instead of defining above function.

    cntrlrCandidate = $controller('cntrlrCandidate', {'$scope': scope});
    

    EDIT :

    Your controller required following Dependency HostelManagementService and HostelManagementIndexDBService which you not provided.So,you need to mock up it.

    Add the following script.

    var HostelManagementIndexDBService,HostelManagementService; //declare at top
    
    // add in beforeEach
    HostelManagementIndexDBService = {}; 
    HostelManagementIndexDBService = {};
    module(function($provide) {
      $provide.value('HostelManagementService', HostelManagementService);
      $provide.value('HostelManagementIndexDBService', HostelManagementIndexDBService);
    });
    

    UPDATE :

    describe("ManagemntApp ", function() {
        var HostelManagementIndexDBService, HostelManagementService;
        beforeEach(module('ManagemntApp'));
        var scope;
        var cntrlrCandidate,
            $location;
    
        beforeEach(function() {
    
            HostelManagementService = {};
            HostelManagementIndexDBService = {};
    
    
            module(function($provide) {
                $provide.value('HostelManagementService', HostelManagementService);
                $provide.value('HostelManagementIndexDBService', HostelManagementIndexDBService);
            });
    
            inject(function($controller, $rootScope) {
    
                scope = $rootScope.$new();
                cntrlrCandidate = $controller('cntrlrCandidate', { '$scope': scope });
            })
        });
    
    
        it('return will pass the Amount', function() {
    
            scope.Candidate = {};
            scope.Candidate.Amount = 2000;
            scope.validateAmount();
            expect(scope.IsValidAmount).toEqual(true);
        });
    
    
    });