Alright, so I have been stumbling upon some issue for a long time and I would like to hear an opinion from the rest of community.
First, let's look at some abstract controller.
function Ctrl($scope, anyService) {
$scope.field = "field";
$scope.whenClicked = function() {
util();
};
function util() {
anyService.doSmth();
}
}
Clearly we have here:
$scope
and some service injectedutil()
Now, I'd like to cover this class in unit tests (Jasmine). However, the problem is that I want to verify that when I click (call whenClicked()
) some item that the util()
method will be called. I don't know how to do that, since in Jasmine tests I'm always getting errors that either the mock for util()
hasn't been defined or was not called.
Note: I'm not trying to fix this particular example, I'm asking about testing such code pattern in general. So please don't tell me "what is exact error". I'm asking how to do that, not how to fix this.
I have been trying a number of ways around this:
$scope
in my unit tests as I don't have this function attached to this object (it usually ends with message Expected spy but got undefined
or similar)Ctrl.util = util;
and then verifying mocks like Ctrl.util = jasmine.createSpy()
but in this case Ctrl.util
is not being called so tests failutil()
to be attached to this
object and mocking Ctrl.util
again, with no luckWell, I cannot find my way around this, I would expect some help from JS ninjas, a working fiddle would be perfect.
The controller function you provided will be used by Angular as a constructor; at some point it will be called with new
to create the actual controller instance. If you really need to have functions in your controller object that are not exposed to the $scope but are available for spying/stubbing/mocking you could attach them to this
.
function Ctrl($scope, anyService) {
$scope.field = "field";
$scope.whenClicked = function() {
util();
};
this.util = function() {
anyService.doSmth();
}
}
When you now call var ctrl = new Ctrl(...)
or use the Angular $controller
service to retrieve the Ctrl
instance, the object returned will contain the util
function.
You can see this approach here: http://jsfiddle.net/yianisn/8P9Mv/