What am I doing wrong in the jasmine unit test of angularjs controller?

I am new to angularjs and writing a unit test for a simple controller. But somehow it is not working. The code goes as follows:

ResetPwdCtrl.js (Have mentioned only the function I am testing)

function ResetPwdCtrl($scope, $modalInstance, Employee, emp){
$scope.emp= emp; 
$scope.confirm = function(){
    Employee.sendResetPwdLink(emp.id).success(function(){
        $modalInstance.close();
    }).error(function(errorObject){
        $scope.alert = {
                type: 'danger',
                text: errorObject.statusCode
         }; 
    });
};
}]);

"Employee" is a factory and sendResetPwdLink is a static method. The unit test for it is

describe("Reset pwd", function() {
var scope, mockModalInstance, mockEmployee, emp, q, deferred, appCtrl;

beforeEach(function() {
     mockEmployee = {
            id : 0,
            sendResetPwdLink : function(theId) {
                mockEmployee.id = theId;
                deferred = q.defer();
                 deferred.promise.success = function(fn) {
                    return deferred.promise.then(fn);
                };
                //return deferred.promise;

                deferred.promise.error = function(fn) {
                    return deferred.promise.fail(fn);
                 };
                return deferred.promise;
            }
        };

        emp = {
             id : 10
        };

        mockModalInstance = {
             isClosed : false,
            close : function() {
                mockModalInstance.isClosed = true
             }
         };
});

beforeEach(inject(function($controller, $rootScope, $q) {
    scope = $rootScope.$new();
    q = $q;

    $controller('ResetPwdCtrl', {
        '$scope' : scope,
        '$modalInstance' : mockModalInstance,
        'Employee' : mockEmployee,
        'emp' : emp
    });
}));

it("confirm", function() {
    scope.confirm();
    deferred.resolve();
    scope.$root.$digest();
    expect(mockModalInstance.isClosed).toEqual(true);
});

it("confirm2", function() {
    scope.confirm();
    deferred.reject({errorObject:[{type: 'danger', statusCode: 401,text: statusCode}]});
    scope.$root.$digest();
});
});

While running the test I am getting following error:

Reset pwd it confirm <<< FAILURE! * TypeError: 'undefined' is not a function (near '...}).error(function(errorObjec...') in resetPwdCtrl.js

Reset pwd it confirm2 <<< FAILURE! * TypeError: 'undefined' is not a function (near '...}).error(function(errorObjec...') in resetPwdCtrl.js

I did not get much help on this error online.Please help!!

Upvotes: 0

Views: 510

Answers (3)

Thank you for the responses, it did help me a lot :)

I checked the error condition where I was writing

deferred.promise.error = function (fn) {
    return deferred.promise.fail(fn);
};

Instead I added the following code to check for error condition

deferred.promise.error = function (fn) {
    deferred.promise.then(null, fn);
    return deferred.promise;
};

This one worked just fine!!

Upvotes: 0

Onosa
Onosa

Reputation: 1273

I woudl try two things. It is possible that q is not defined. You may try changing the beforeEach before the mockEmployee definition to this...

beforeEach(inject(function($q) { //ADD INJECT
q = $q //DEFINE q
     mockEmployee = {...//This part looks good to me

If that doesn't help, this is how I use q in my tests. Hopefully, it will lead you to the right track.

getData = {
        get: function (id)
        {
            deferred = q.defer();
            // Place the fake return object here
            deferred.resolve(mockEmployee);
            return { $promise: deferred.promise };
        }
    };
    $rootScope.$apply();

Upvotes: 0

Bhavana Johri
Bhavana Johri

Reputation: 347

describe("ResetPwdCtrl",function(){

var $rootScope,$modalInstance,ctrl;

beforeEach(module('MyApp'));
beforeEach(inject(function($injector,_Employee_,_emp_,$controller){

$rootScope=$injector.get('$rootScope');
scope=$rootScope.$new();
$modalInstance=$injector.get('$modalInstance');
ctrl=$controller(function($scope:scope){
});

}));

it('should call the confirm()',function(){
scope.confirm();
expect(scope.alert.type).toEqual('danger');
});
});

please do declare the JSON object if scope.alert.type is undefined.

hope this post will help you

Upvotes: 1

Related Questions