I have xf array: var xf = [];
And I have a function is a element in this array and a function to use it:
$scope.checkEmailValid = function () {
var result = false;
Iif (xf.validateEmail($scope.email, '256')) {
result = true;
}
return result;
};
xf.validateUsername = function (sText) {
var isValid = false;
do {
//Check for valid string.
isValid = typeof sText === 'string';
if (!isValid) {
break;
}
//Check that each special character does not exist in string.
for (var i = 0; i < sText.length; i++) {
if (xf.SPECIAL_CHARS.indexOf(sText.charAt(i)) !== -1) {
isValid = false;
break;
}
}
if (!isValid) {
break;
}
} while (false);
return isValid;
};
But when I run my spec:
it ('checkEmail', function(){
$controller('MyCtrl', { $scope: $scope });
xf.validateUsername();
spyOn(window,xf.validateUsername).and.callThrough();
});
It makes an error:
xf.validateUsername is not a function
How can I cover it?
Create an Angular project with jasmine and karma By doing this, the jasmine and karma configuration is resolved for us. Install and create a new project with angular-cli: Install npm -g @angular/cli. Ng new angular-unit-testing angular unit-testing.
Jasmine is a behavior development testing framework. Unit tests are written using Jasmine and are run to see if individual parts of an application are working correctly. As a result, unit tests will either pass or fail depending on if the code is working correctly or has a bug.
The xf
variable is not acessible from the outside of the controller's scope (i.e. not accessible in the unit test files).
You must've done the following thing:
angular
.module('myModule')
.controller(function ($scope) {
var xf = [];
// etc.
});
You could attach the xf
variable to the MyController instance once Angular instantiates it:
angular
.module('myModule')
.controller(function ($scope) {
this.xf = [];
// etc.
});
But that's not really a clean way of doing it. A better way (in my opinion) would be to create a factory:
angular
.module('myModule')
.factory('xfService', function () {
var xf = [];
function validateUsername(text) {
// etc.
}
function get() {
return xf;
}
return {
get: get,
validateUsername: validateUsername
};
});
Now, you can inject the factory in your controller to use xf:
angular
.module('myModule')
.controller(function ($scope, xfService) {
// somewhere
var isValid = xfService.validateEmail($scope.email, '256');
// to get the values in the array
var values = xfService.get();
});
Finally, for the unit tests, it becomes really easy to test the validateEmail
method.
describe('Unit tests - xfService', function () {
var xfService;
beforeEach(angular.module('myModule'));
beforeEach(angular.inject(function (_xfService_) {
xfService = _xfService_;
});
});
describe('xfService.validateUsername', function () {
it('should return a boolean value', function () {
// for example
expect(typeof xfService.validateUsername('test')).toBe('boolean');
});
// add more unit tests to check that the method works as expected
});
});
You'll need to add the angular-mocks
file to the Karma config.
Thanks to Paul Podlech and Claies for the hints in the comments/answers.
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