Testing named function within a Controller
Solution 1
In a sense, using functions like that is private, and cannot be accessed from outside the function. Take a look at this link: http://javascript.crockford.com/private.html
Essentially what is said is that have a function/object in javascript, anything with a this.
prefix is public, and anything with a var
prefix is private.
For Angular, you can definitely have private variables and functions, if not just to lessen the memory usage of the $scope
variable. Private functions should be called by your $scope
objects to get values to be displayed/used by the user. Try changing it to this:
.controller( 'DummyCtrl', function DummyCtrl($scope){
var doSomething = function() {
return "blah";
};
$scope.something=doSomething();
})
And then testing the private function with:
describe( 'DummyCtrl', function(){
var scope = {},
ctrl = new DummyCtrl(scope);
it('should do something', function(){
expect(scope.something).toMatch('blah');
});
});
Solution 2
The function DummyCtrl
you are providing for the controller registration will be used by Angular as a constructor. If you need the controller instance to expose the function doSomething
without attaching it to the $scope
, you should attach it to this
.
Try changing
var something = function(...
to
this.something = function(...
and your test should work.
You can see this approach here: http://jsfiddle.net/yianisn/8P9Mv/. Also have a look at this SO question: How to write testable controllers with private methods in AngularJs?
jbenowitz
Updated on July 28, 2022Comments
-
jbenowitz almost 2 years
A newbie Jasmine/Angular question.
I have a named function within a controller like so:
.controller( 'DummyCtrl', function DummyCtrl($scope){ var doSomething = function() { return "blah"; }; })
I need to test this function, and am trying to by calling the following Jasmine spec:
describe ('myApp', function(){ var $scope, $controller; var DummyCtrl; beforeEach(module('myApp')); describe('controllers', function(){ beforeEach(inject(function ($controller, $rootScope){ $scope = $rootScope.$new(); DummyCtrl = $controller('DummyCtrl', {$scope: $scope}); })); describe( 'DummyCtrl', function(){ var blah; beforeEach(function(){ blah = DummyCtrl.doSomething(); }); it('should do something', function(){ expect(blah).toContain("blah"); }); }); }); });
Instead of things working out, I result in the following error:
TypeError: Object #<DummyCtrl> has no method 'doSomething'
. I'm assuming this is something super simple that I'm not understanding. -
jbenowitz about 11 yearsthat did the trick. I was hoping I could call these private functions to streamline some unit tests (on $scope functions that call these methods). But I'm sure I can figure out a way to do it using what calls them.
-
Dzung Nguyen over 10 yearsthis should be marked as the answer. The other one doesn't do the problem fully.