I've been immersed in writing tests for the past few weeks. In my workplace, we utilize Mocha as our test runner and Chai for assertions, with Sinon for creating stubs. However, there's a recurring issue that's been bothering me. I've written tests for several functions where I stub out every dependency without considering the arguments passed to the function being tested. Let me illustrate with an example:
module.exports = {
"someFunc": (arg1, arg2) => {
return new Promise((resolve, reject) => {
Promise.all(arg1).then(data => {
let someArray = ourHelperLib.toArray(data);
let someObj = ourHelperLib.toObject(arg2);
if(someArray.length == 0){
reject("error");
}else{
resolve({
"array": someArray,
"object": someObj
});
}
}).catch(err => {
reject(err);
});
});
},
}
- When testing this function, I've created a scenario where I stub
Promise.all()
to throw an error. - In another test, I stub
Promise.all()
to return false andourHelperLib.toArray()
to throw an error, checking how the function handles it. - For a third test, I stub all three:
Promise.all()
,ourHelperLib.toArray()
, andourHelperLib.toObject()
to return false values and assess the output for a resolved promise after completing the operations.
It's evident from the function definition that the arguments are directly passed to the stubbed dependencies, leading me to overlook these values completely, like this:
const stubOurHelperLibToThrowError = argFromCaller => {
throw new Error("This is an error");
}
By neglecting the argument handling within my stub functions, I realize I'm not effectively testing the input data of the function. Instead, I focus solely on validating the logic structure of someFunc()
.
Is this approach considered best practice? Seeking clarity on this topic as I aim to establish comprehensive guidelines for unit testing at my current workplace.
Peace!