Photo by Lubo Minar / Unsplash

Why

Some libraries like Ora have set their module.exports to a function.

const oraFactory = function (opts) {
return new Ora(opts);
};
module.exports = oraFactory;
view raw ora-exports.js hosted with ❤ by GitHub

Testing libraries like Sinon rely on having an object to stub on, for example:

const stub = sinon.stub(obj, 'method');

If there is no object you can't stub the function, which makes libraries like Ora 'unstubable' out of the box. There is a certain frustration about it with no clear solution.

How

One possible solution for the problem is to create a proxy module with cache to allow stubbing.

// in order to properly stub and mock libs which export function by default
// more https://github.com/sinonjs/sinon/issues/562
export const cache = {};
export default function(lib) {
const module = require(lib);
if (!cache.hasOwnProperty(lib)) cache[lib] = module;
return () => cache[lib].apply(this, args);
}
view raw stub-path.js hosted with ❤ by GitHub

Import it in your code const lib = patch('lib'); and use cache object in your tests.

import { cache } from './patch';
const stub = sinon.stub(cache, 'lib');
view raw stub-proxy.js hosted with ❤ by GitHub

The obvious downside is that you have to import your libs like const lib = patch('lib');

Would love to find a better approach. If know one please let me know.