Possibly a naive question but I have a class similar to(mine has more data read from database and caching them):
var genericClass = class {
constructor() {
this.genericStructure = {};
}
async getState(key) {
//some more core logic
return this.genericStructure[key];
}
async putState(key, genericJson) {
this.genericStructure[key] = genericJson;
return true;
}
}
its getState
and putState
are used multiple times in a consumer class, I want to mock all these occurences from a local map
object in my test class. Can it be done?
I am using chai, mocha, sinon
"devDependencies": {
"chai": "^4.1.2",
"chai-as-promised": "^7.1.1",
"eslint": "^4.19.1",
"mocha": "^5.2.0",
"nyc": "^12.0.2",
"sinon": "^6.0.0",
"sinon-chai": "^3.2.0"
}
Instead of letting your class initialize the structure it wants, you should provide (inject) it the the structure on initialization. This is the principle of Dependency Injection ( Constructor injection ).
var genericClass = class {
constructor(initialStructure) {
this.genericStructure = initialStructure;
}
async getState(key) {
//some more core logic
return this.genericStructure[key];
}
async putState(key, genericJson) {
this.genericStructure[key] = genericJson;
return true;
}
}
And now in your tests you can pass whatever you like for initialStructure
.
Updated Answer
From your comment seems like the question was a little confusing. I think what you need is to mock the class methods as well to change their functionality, and at the same time support dependency injection. You can use something like below -
function testClassProxy(map) {
let handleSetProps = function(args){
map.set(args[0], args[1]);
return true;
}
let handleGetProps = function(args){
return map.get(args[0]);
}
let handler = {
get(target, propKey) {
return function (...args) {
switch(propKey){
case 'setProps':{
return handleSetProps(args)
}
case 'getProps': {
return handleGetProps(args)
}
}
};
}
};
return new Proxy(map, handler);
}
let proxy = testClassProxy(new Map());
console.log(
proxy.setProps('a', '1'),
proxy.getProps('a')
);