Last active
October 23, 2021 23:22
-
-
Save guybedford/e6687e77d60739f27d1b5449a2872bf4 to your computer and use it in GitHub Desktop.
Node.js mocking example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const mocks = Object.create(null); | |
global.mock = function (_mocks) { | |
Object.assign(mocks, _mocks); | |
}; | |
export async function resolve (specifier, context, parentResolve) { | |
if (mocks[specifier]) { | |
return { url: 'mock:' + specifier }; | |
} | |
return parentResolve(specifier, context); | |
} | |
export async function getFormat(url, context, parentGetFormat) { | |
if (url.startsWith('mock:')) { | |
return { format: 'dynamic' }; | |
} | |
return parentGetFormat(url, context, parentGetFormat); | |
} | |
export async function dynamicInstantiate (url) { | |
const obj = mocks[url.slice(5)]; | |
const exports = Object.keys(obj); | |
return { | |
exports, | |
execute (ns) { | |
for (const key of exports) | |
ns[key].set(obj[key]); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
node --loader ./mock-loader.mjs test.mjs | |
# Alternatively, locate at node_modules/mock-loader/loader.mjs with a package.json "exports": "./loader.mjs" set | |
# Then use something like: | |
# NODE_OPTIONS="--loader mock-loader" node test.mjs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
mock({ | |
express: { | |
custom: 'express' | |
} | |
}); | |
import('express').then(x => console.log(x)); |
Can you clarify your point here further?
Jest mocks rely on transpiling instead of using any proper real-time esm mechanism. Essentially they are fundamentally incompatibile with Node.js esm implementation - they sidestep it completey as they are fully transpiling everything.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
They can't! Rather, the main thread
mock
call would use a unique identifier that can serialize to the loader thread, that then coordinates that the binding run through themock
call is used for the main thread module instance. That is, the binding is still created, setup and shared on the main thread, but the loader on the other thread has to coordinate that through a serialization interface over having access to the binding explicitly.If you consider the mocking example above enough capability, then I can guarantee that the capability will remain possible despite any future API changes. The API just won't necessarily be stable. It should be possible for a userland mocking API to be created that provides a stable interface to users working over all the unstable versions. Happy to discuss collaboration further there too if you like.
Can you clarify your point here further?