I'm converting some old JS code to TS, and the tests all use mocha/sinon with stubbing of functions using old require
style imports without destructuring, and also rely on the application code to do the same.
So when the application code does
import {someFunc} from 'mymodule'
and the tests do
const mymodule = require('mymodule');
sinon.stub(mymodule, 'someFunc', ...)
... then someFunc
won't be stubbed by the application since it was bound at compile time due to the destructuring. I think every developer trying to modernize old JS code has run into this problem. :(
Now, as hesitant as I am to using old-school import * as mymodule
in my application code and call functions in that module using mymodule.someFunc()
, I can sort of live with that to get the tests working. BUT, here comes the caveat - there are also some cases where modules use other functions in the same module which are stubbed by tests:
// mymodule.ts
export function someFunc() {
return someOtherFunc();
}
export function someOtherFunc() {
return 42
}
// mymodule.test.js
const mymodule = require('mymodule');
sinon.stub(mymodule, 'someOtherFunc');
The tests will fail to stub someOtherFunc
since it's already bound at compile time when someFunc
calls it.
Here, a solution I've found to work is that the module uses exports.someOtherFunc()
to call a function in the same module, and while this is even uglier, a more severe problem is that exports
is typed as any
, losing all type safety.
I know that the proper solution probably is to refactor the entire application to have modules return objects, classes or similar (which enables stubbing properties within these objects) instead of separate functions - but I don't really have time to rewrite the entire application. Is there some solution that at least maintains type safety when calling sibling functions in the same module via the exports
object? The only other solution I've come up with is to split modules into smaller pieces so that no function calls another function in the same module which needs to be stubbed for tests, but this will also be a substantial piece of refactoring.