Sunday, May 12, 2024
 Popular · Latest · Hot · Upcoming
29
rated 0 times [  33] [ 4]  / answers: 1 / hits: 16333  / 10 Years ago, mon, july 28, 2014, 12:00:00

I am using jasmine for testing my angular controllers.
I am catching errors and success in the .then(successCallback, errorCallback)
Although it is working fine on the bases of live functionality but am confused how to write a spy for returning an error as it is always caught in the successCallback()



Following is the controller :-



angular.module('myApp')
.controller('LoginCtrl', function ($scope, $location, loginService, SessionService) {
$scope.errorMessage = '';

$scope.login = function () {

var credentials = {
email: this.email,
password: this.password
};

SessionService.resetSession();
var request = loginService.login(credentials);

request.then(function(promise){ //successfull callback
if (promise['status'] === 200){
//console.log('login');
$location.path('/afterloginpath');
}
},
function(errors){ //fail call back
// console.log(errors);
$location.path('/login');
});
};
});


My test case :-



'use strict';

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

// load the controller's module
beforeEach(module('myApp'));

var LoginCtrl, scope, location, login, loginReturn, session;
var credentials = {'email': '[email protected]', 'password': 'admin123'};

// Initialize the controller and a mock scope
beforeEach(inject(function ($controller, $rootScope, $location, _loginService_, _SessionService_) {

scope = $rootScope.$new();
LoginCtrl = $controller('LoginCtrl', {
$scope: scope
});

location = $location;
login = _loginService_;
session = _SessionService_;
scope.errorMessage = '';
spyOn(login, login).andCallFake(
function(){
return {
then: function(response){
response(loginReturn);
}
}
}
);

spyOn(session, setName).andCallFake(function(){
return true;
});
}));

it('should go to login when login fail', function () {
loginReturn = function(){
return{
successfullyCallback: {throwError:true},
failCallback: {status: 400, 'data' : {'errors' : [{type:invalid_data,target:email,password}]}}
}
};

var wrong_creds = {email: '[email protected]', password: 'wrong_password'};
scope.email = wrong_creds.email;
scope.password = wrong_creds.password;

scope.login();

expect(location.path()).toBe(/login);
expect(scope.errorMessage).toBe('username or password combination is invalid');
});

});

More From » angularjs

 Answers
8

I find it easier to use actual promises for mocked services as it removes a lot of nested functions and is a lot easier to read.



Relevant snippets ($q needs to be injected in beforeEach):



deferred = $q.defer();
spyOn(login, 'login').andReturn(deferred.promise);

...

deferred.reject({ ... });


After resolving or rejecting the promise you need to call scope.$digest() so angular can process it.


[#70017] Friday, July 25, 2014, 10 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
jaelynncherokeeg

Total Points: 697
Total Questions: 109
Total Answers: 104

Location: France
Member since Thu, Mar 18, 2021
3 Years ago
jaelynncherokeeg questions
Thu, May 27, 21, 00:00, 3 Years ago
Fri, Jan 24, 20, 00:00, 4 Years ago
Thu, Nov 14, 19, 00:00, 5 Years ago
Wed, Sep 18, 19, 00:00, 5 Years ago
;