I've been trying to spy a function that was executed on the initialize of a controller, but the test always failed.
I've been trying execute $scope.$digest()
and this it's not working, However in the console, i see that the function have been called.
I can't figure out this, Someone can explain to me why this it's not working?
Codepen Example: http://codepen.io/gpincheiraa/pen/KzZNby
Controller
function Controller($stateParams, $scope){
$scope.requestAuthorization = requestAuthorization;
if ($stateParams.requestAuthorization === true) {
console.log('$stateParams.requestAuthorization');
$scope.requestAuthorization();
}
function requestAuthorization() {
console.log('requestAuthorization()');
}
}
Testing
describe('AppCtrl', function(){
var AppCtrl, $rootScope, $scope, $stateParams;
beforeEach(module('exampleApp'));
beforeEach(inject(function($controller, _$rootScope_, _$injector_, _$stateParams_) {
$rootScope = _$rootScope_;
$scope = $rootScope.$new();
$stateParams = _$stateParams_;
$stateParams.requestAuthorization = true;
AppCtrl = $controller('AppCtrl',{
$scope: $scope,
$stateParams : $stateParams
});
spyOn($scope, 'requestAuthorization');
}));
it('$stateParams.requestAuthorization should be defined', function() {
expect($stateParams.requestAuthorization).toBeDefined();
});
it('$scope.requestAuthorization should be defined', function() {
expect($scope.requestAuthorization).toBeDefined();
});
// this test is not passing..
it('should call requestAuthorization', function() {
//$scope.$digest();
expect($scope.requestAuthorization).toHaveBeenCalled();
});
});
A Spy is a feature of Jasmine which lets you take an existing class, function, or object and mock it in such a way that you can control what gets returned from function calls. We create a real instance of AuthService and inject it into the LoginComponent .
A Jasmine spy can stub any function and track all calls to that function and all of its arguments. Jasmine Spies are a powerful tool to use in unit testing because they allow us to focus on the function that is being tested.
Your test is failing because spy gets overridden by real function when controller initializes. One way to avoid this is monkey-patching $scope
object with custom setter for requestAuthorization
property, that could create spy when controller is trying to assign value to this property:
beforeEach(inject(function($controller, _$rootScope_, _$injector_, _$stateParams_) {
$rootScope = _$rootScope_;
$scope = $rootScope.$new();
var reqAuthSpy;
Object.defineProperty($scope, 'requestAuthorization', {
get: function() {return reqAuthSpy;},
set: function(fn) {
reqAuthSpy = jasmine.createSpy('reqAuthSpy');
}
});
$stateParams = _$stateParams_;
$stateParams.requestAuthorization = true;
AppCtrl = $controller('AppCtrl',{
$scope: $scope,
$stateParams : $stateParams
});
}));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With