Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
174
rated 0 times [  175] [ 1]  / answers: 1 / hits: 5607  / 11 Years ago, thu, january 2, 2014, 12:00:00

I am trying to test an AngularJS file, but it can't call a method defined in another Controller.



In the MyPage file:



angular.module('MyApplication').controller('MyPageCtrl', function ($scope, $rootScope) {
if($scope.pageChecker) {
$scope.doSomething();
}
}


The pageChecker() method is defined in App.js, in the MyApplication controller, and returns true or false.



For the sake of completeness:



$scope.pageChecker = function() {
if(cookieCheck) {
return true;
}
else {
return false;
}
};


The jasmine file is:



describe(Page check, function(){
beforeEach(angular.mock.module('MyApplication'));

beforeEach(angular.mock.inject(function ($rootScope, $controller) {
var $scope = $rootScope.$new();
$controller('MyPageCtrl', { $scope: $scope});
}));

it(should call $scope.doSomething, function(){
spyOn($scope, doSomething);
$scope.doSomething();
expect($scope.doSomething).toHaveBeenCalled();
});
});


I get TypeError: 'undefined' is not a function (evaluating '$scope.pageChecker()')



I want to override the pageChecker method to always return true. How do I do this?



EDIT: Thanks to Dskh, I have my answer, with another tweak from me:



describe(Page check, function(){

var $scope; //declare here, else it is a local variable inside the beforeEach

beforeEach(angular.mock.module('MyApplication'));

beforeEach(angular.mock.inject(function ($rootScope, $controller) {
$scope = $rootScope.$new();
// define the overriding methods here
$scope.pageChecker = function(){
return true;
};
// end overriding methods here
$controller('MyPageCtrl', { $scope: $scope});
}));

it(should call $scope.doSomething, function(){
spyOn($scope, doSomething);
$scope.doSomething();
expect($scope.doSomething).toHaveBeenCalled();
});
});

More From » angularjs

 Answers
3

You create the $scope yourself when you do $rootScope.$new(), and then you inject it into the controller you create when you use the $controller() method.



Therefore, if you want that method to always return true, you just need to create the method yourself:



beforeEach(angular.mock.inject(function ($rootScope, $controller) {
var $scope = $rootScope.$new();

$scope.doSomething = function(){
return true;
};

$controller('MyPageCtrl', { $scope: $scope});
}));


Some more explanation: When your app is running for real, $scope is injected automatically into your controller by angular. In your test you are just testing your controller in isolation, so you need to create the scope object yourself and fake any behaviour you want from it. Using $rootScope().$new() will give you the angular methods like $watch or $on, but you need to recreate your own methods yourself.


[#49052] Wednesday, January 1, 2014, 11 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
andrewb

Total Points: 259
Total Questions: 124
Total Answers: 90

Location: Ivory Coast
Member since Sun, Mar 7, 2021
3 Years ago
;