Updated : In this controller I am trying to test the user login process and it calls loginRequest method in WebService to send out user credentials as a login message. A loginreply message is received by the controller.If login process is successful a URL redirection should happen.I have used jasmine spy objects to mock the WebService functionality.
There were some questions along similar lines and they did help me somewhat to narrow down the problem scope. But I am still facing some problems in getting this unit test function properly.so I decided to post an Update to my initial question.
Useful Stack Overflow Questions
- How to unit test Angular controller with $scope.$on?
- $scope.$emit and .$on angularJS
- How can I test events in angular?
Useful external resources
But I am currently having a problem evaluating the received message status and evaluating URL redirection process.How do I test that the scope is populated after the broadcast ($scope.msg)? This works perfectly in the app itself, just don't know how to test it.
I have a controller with an event listener in my Angular app, defined as follows.
AngularJS code
Apps.controller('loginCtrl',['$scope','$location','WebService','$timeout','$log','$http',
function($scope,$location,WebService,$timeout,$log,$http)
{
$scope.login = function()
{
var loginMsg = {};
loginMsg.UserName = $scope.username;
loginMsg.Password = $scope.password;
WebService.loginRequest($location.host(),$location.port(),"Check","'?'",loginMsg);
}
//Error attempting to access msg in Unit test
$scope.$on('LSuccess_msg',function(e,msg)
{
//These variables can be accessed in the Unit test
$scope.myEventCalled = true;
$scope.response = msg;
if(angular.equals(msg.Status,"LOGIN_SUCCESS"))
{
$timeout(function ()
{
//Need to test this
window.location.href = "http://"+<--custom redirection URL is added here-->;}, 5);
}
});
}]);
Unit test used to test controller
"use strict";
describe("Controller : Login controller", function() {
var $scope, ctrl, $location, $timeout, WebService, httpBackend, msgdata;
beforeEach(module('Apps'));
beforeEach(inject(function($rootScope, $controller, _$timeout_, _$location_, $httpBackend){
$scope = $rootScope.$new();
$timeout = _$timeout_;
$location = _$location_;
httpBackend = $httpBackend;
var loginMsg={};//populate message
msgdata={EMail:"v@v.com",FullName:"Viranga Indira",SessionId:"1114335860", Status:"LOGIN_SUCCESS",
UserID:"c7232d47",_msgType:"com.ust.sharedmsgs.LoginReply_msg",
};
WebService = jasmine.createSpyObj(WebService, ["loginRequest"]);
WebService.loginRequest($location.host(),$location.port(),"Check","'?'",loginMsg);
ctrl = $controller('loginCtrl',{
$scope: $scope,
$location: $location,
WebService: WebService,
$timeout: $timeout
});
$scope.$digest();
}));
describe("Controller : Login controller", function(){
it("creates spies for the requested Service", function() {
expect(WebService.loginRequest).toBeDefined();
});
it("tracks that the spies were called", function() {
expect(WebService.loginRequest).toHaveBeenCalled();
});
it('should call loginRequest WebServiceMock', function ()
{
$scope.username = 'v@v.com';
$scope.password = 'viranga123';
$scope.$digest();
$scope.login();
expect($scope.username).toEqual('v@v.com');
expect($scope.password).toEqual('viranga123');
expect(WebService.loginRequest).toHaveBeenCalled();
});
var $rootScope;
beforeEach(inject(function($injector) {
$rootScope = $injector.get('$rootScope');
$rootScope.$broadcast('LSuccess_msg', msgdata);
}));
describe("Boradcast response", function() {
it("should broadcast Response message", function() {
expect($scope.myEventCalled).toBe(true);
expect($scope.msg).not.toBe(null);
//$scope.msg.Status check fails
//expect($scope.msg.Status).toEqual('LOGIN_SUCCESS');
//$scope.response related checks can be evaluated
expect($scope.response).not.toBe(null);
expect($scope.response.EMail).toEqual('v@v.com');
expect($scope.response.Status).toEqual('LOGIN_SUCCESS');
expect($scope.response.FullName).toEqual('Viranga Indira');
});
});
});
});
Error Message thrown if expection is uncommented
Chrome 36.0.1985 (Windows 7) Controller : Login controller Controller : Login controller
Boradcast response should broadcast Response message FAILED
TypeError: Cannot read property 'Status' of undefined at null.<anonymous>
Any leads on how I can test the received message status (e.g. $scope.msg.Status) and how to test URL redirection process would be much appreciated. Why is $scope.msg.Status inaccessible in this test ?
Can Spy Objects be used further to improve these test especially to test $scope.$on in AngularJS?