My Angular module, validation, is declared as follows:
(function(ns){
ns.validation = angular.module("validation", []);
})(blog);
Within this module are two services: validator and validationRulesProvider. Here is the structure of those services:
(function(module){
module
.factory("validationRulesProvider", function(){
var _getRules = function() {
return [{
isValid: function(post) {
return post.length > 0;
}
}];
};
return {
getRules: _getRules
};
});
})(blog.validation);
and
(function(module){
module
.factory("validator", ["validationRulesProvider", function(validationRulesProvider){
var _validate = function(post) {
var rules = validationRulesProvider.getRules();
for (var rule in rules) {
if (!rule.isValid(post)) {
return false;
}
}
return true;
};
return {
validate: _validate
};
}]);
})(blog.validation);
I am attempting to test certain functionalities using Jasmine:
- The getRules method on validationRulesProvider is actually called from the validate method
- The post parameter is run through each rule returned from said method
Below is my Jasmine test script:
describe("Validator: ", function(){
var _validator;
var _mockedValidationRulesProvider;
var _mockRule;
beforeEach(function(){
module("validation");
inject(function(validationRulesProvider){
_mockedValidationRulesProvider = validationRulesProvider;
});
_mockRule = jasmine.createSpy();
spyOn(_mockedValidationRulesProvider, "getRules")
.and
.returnValue([{
isValid: _mockRule
}]);
inject(function(validator){
_validator = validator;
});
});
describe("getRules - ", function(){
it("gets a collection of rules from the rules provider", function(){
_validator.validate("");
expect(_mockedValidationRulesProvider.getRules).toHaveBeenCalled();
});
it("should pass the post through each rule received from the rules provider", function(){
expect(_mockRule.calls.count()).toEqual(_mockedValidationRulesProvider.getRules().length);
});
});
});
Despite setting up the spy for validationRulesProvider.getRules correctly, both tests are failing. Changing the return value of the spy to an empty array allows the first test to pass, indicating that the loop in validator.validate is not being entered.
Karma output states:
PhantomJS 1.9.8 (Windows 7) Validator: getRules - gets a collection of rules from the rules provider FAILED TypeError: 'undefined' is not a function (evaluating 'rule.isValid(post)') at C:/Users/User/JS/Angular/Learning/blogsite/scripts/validation/validator.js:8 at C:/Users/User/JS/Angular/Learning/blogsite/scripts/tests/validator.test.js:32 PhantomJS 1.9.8 (Windows 7) Validator: getRules - should pass the post through each rule received from the rules provider FAILED Expected 0 to equal 1. at C:/Users/User/JS/Angular/Learning/blogsite/scripts/tests/validator.test.js:37 PhantomJS 1.9.8 (Windows 7): Executed 5 of 5 (2 FAILED) (0 secs / 0.039 secs)
I'm puzzled about why the tests are failing when I believe the spy setup is correct. The return object matches what is expected from the actual implementation of the function. What could be causing this issue?