I know that this is not necessarily the answer you are looking for, but I have found that most of the time if a private function is worth testing, it's worth being in its own file.
E.g., instead of having private methods in the same file as the public ones, like this...
src/thing/PublicInterface.js
function helper1 (x) {
return 2 * x;
}
function helper2 (x) {
return 3 * x;
}
export function publicMethod1(x) {
return helper1(x);
}
export function publicMethod2(x) {
return helper1(x) + helper2(x);
}
...you split it up like this:
src/thing/PublicInterface.js
import {helper1} from './internal/helper1.js';
import {helper2} from './internal/helper2.js';
export function publicMethod1(x) {
return helper1(x);
}
export function publicMethod2(x) {
return helper1(x) + helper2(x);
}
src/thing/internal/helper1.js
export function helper1 (x) {
return 2 * x;
}
src/thing/internal/helper2.js
export function helper2 (x) {
return 3 * x;
}
That way, you can easily test helper1
and helper2
as-is, without using Rewire and other "magic" (which, I have found, have their own pain points while debugging, or when you try to make your move towards TypeScript, not to mention poorer understandability for new colleagues). And them being in a sub-folder called internal
, or something like that, will help avoiding accidental usage of them in unintended places.
P.S.: Another common issue with "private" methods is that if you want to test publicMethod1
and publicMethod2
and mock the helpers, again, you normally need something like Rewire to do that. However, if they are in separate files, you can use Proxyquire to do it, which, unlike Rewire, doesn't need any changes to your build process, is easy to read and to debug, and works well even with TypeScript.