They say:
"You should test the interface, not the implementation."
In other words, you should be concerned with the end result, not with how it is accomplished (black box testing).
It is also said that you should not test private functions, rather only the public interface that is exposed. But my question is...
What do you do about a publicly exposed interface (e.g., function) that is dependent upon several subtasks that are private? How should you go about testing that?
Consider the below function calculateDiscountedPrice
. Let's pretend that the first function is publicly available (think export default) and the other 3 are private.
// PUBLIC TOP-LEVEL FUNCTION
export default function calculateDiscountedPrice(price, discount) {
const dollarsOff = getDollarsOff(price, discount);
return round(price - dollarsOff);
}
// PRIVATE SUBTASK
function getDollarsOff(price, discount) {
return price * discount;
}
// PRIVATE SUBTASK
function round(number, precision = 2) {
return isInt(number)
? number
: number.toFixed(precision);
}
// PRIVATE SUBTASK
function isInt(number) {
return number % 1 === 0;
}
Example usage:
console.log(calculateDiscountedPrice(100, 0.75)) // 25
As you can see, calculateDiscountedPrice
is the public function we are exposing, so we should unit test that. But what about the three other subtasks? Why shouldn't we test those? Would the tests that cover calculateDiscountedPrice
cover the other three as well?