mardi 24 mars 2015

Angular, Karma/Jasmine/Chai/Sinon testing of a provider

I am having a bit of an issue testing an object constructor in a provider I have set up here. It lets users set up objects in their .config so I can then reference them later to check validity of requested objects (keeps a reference for checking as a short answer).


So I have it all set up and working great, however I'm trying to get some unit testing integrated with this and am running into some trouble.


So I pulled out the guts of the functions (they wont really help here) and here's what I have :



$moduleObjectProvider.$inject = [];

function $moduleObjectProvider() {

var currentModules = {};

//outer closure to inject "this"
function outerAddState(moduleObj) {
return function(stateName, stateOptions) {
//extend currentModules with verified state/module;
}

//outer function so we can push into module (closure)
function modulePush(currentModule, name) {
var tempMod = {};
tempMod[name] = currentModule;
_.extend(currentModules, tempMod);
}

this.$get = $get;

$get.$inject = ['URLfactory', '$log', '$location'];

function $get(URLfactory, $log, $location) {

return {
goState: function(name, stateName, options) {
if (currentModules[name]) {
this.prepState(name, stateName, options);
} else {
}
},
prepState: function(name, stateName, options) {
if (currentModules[name].states[stateName]) {
//
} else {
//throw error
$log.error("Requested Module exists, but state does not.");
}
},
moduleConstructor: function(name, cb) {
if (currentModules[name]) {
//throw error
$log.warn(name + " module already exists.");
} else {
this.states = [];
this.callback = cb;
this.addState = outerAddState(this);
modulePush(this, name);

}
},
modules: function() {
return currentModules;
}
};
}
}

angular.module(metadata.moduleName, []).provider(metadata.componentName, $moduleObjectProvider);


Excuse the require.js naming convention. So this is owrking great, however where I am having trouble is testing the prepState() and goState() functions. This is mostly because they reference the currentModules object. I can push a module into it but I cannot seem to get the addstate functions to fire correctly within the unit tests.


So in the normal scenario, in the .config (with this provider injected) I can just do something like this -



new ($moduleObjectProvider.$get()).moduleConstructor("module1", callback)
.addState("newState", ["day", "week", "month"]);


This pushes in a new module and it's states. However in the unit test I have only gotten this far (inside a test) -



var callback = function(a, b) {};
URLprovider.moduleConstructor("module1", callback);


So, this works fine for JUST pushing the module in, but in order to test prepstate and gostate, i need to push the states inside too, the .addState("newState", ["day", "week", "month"]); chain in the running code.


However I cannot seem to chain, if I try



URLprovider.moduleConstructor("module1", callback).addState("newState", ["day", "week", "month"]);


(just trying chaining onto the working "add just module" part) I get -



TypeError: 'undefined' is not an object (evaluating 'URLprovider.moduleConstructor("module1", callback).addState')


I'm thinking it may be because the this.addState calls a closure function outside of the $get maybe? Is there some way around this, or am I doing this incorrectly? Any insight would be might appreciated, thanks!


Aucun commentaire:

Enregistrer un commentaire