Given an npm package that needs to dynamically load a dependency from the root of the parent/referencing package, and that location isn't known until runtime, it has to do a dynamic require:
// config-fetcher.js
const path = require('path');
const getRunningProjectRoot = require('./get-running-project-root');
module.exports = filename =>
require(path.resolve(getRunningProjectRoot(), filename));
(There's no guarantee that the module will be in node_modules
. It could be symlinked or loaded globally. So it can't use a static require.)
This is simplified from the real code, so unless you know of a way to require files non-dynamically relative to the running project root, this has to be this way.
Now, to test this, I'd prefer not to depend on any file that's actually on disk. However, Jest seemingly won't let you mock a nonexistent file. So if I try this:
const mockFileContents = {};
jest.mock('/absolute/filename.blah', () => mockFileContents);
// in preparation for wanting to do this:
const result = require('./config-fetcher')('/absolute/filename.blah');
expect(result).toBe(mockFileContents);
then I get an error from jest-resolve
, with file Resolver.resolveModule
throwing Error: Cannot find module '/absolute/filename.blah'.
I need to test some of the functionality of this dynamic requiring module, as it handles some cases of relative paths vs. absolute paths, and allows you to specify a special path through a Symbol, with one being for example applicationRoot
, so the module config-fetcher
does the hard work instead of the caller.
Could anyone offer guidance on how to test this module, or how to restructure so dynamic requires aren't needed or they are easier to test?