Using module mocks in Jest has been done since the dawn of time, however as we move into the world of mjs it's impossible to intercept calls to require at runtime to enable this pattern.
jest.mock('./filename')
While I generally try my best to parameterize my dependencies, there are some cases where it's not possible (such as third party dependencies) or it's inconvenient and I need to explicitly mock out a single or multiple properties in a module.
I have tried various ways to reassign a property:
// foo.mjs
export function foo() {
console.log('foo')
}
Simple reassignment - fails
import { foo } from './foo.mjs'
import * as fooModule from './foo.mjs'
fooModule.foo = function() {
console.log('bar')
}
console.log(foo())
Object.defineProperty - fails
import { foo } from './foo.mjs'
import * as fooModule from './foo.mjs'
Object.defineProperty(fooModule, 'foo', { value: function() {
console.log('bar')
}})
console.log(foo())
Object.assign - fails
import { foo } from './foo.mjs'
import * as fooModule from './foo.mjs'
Object.assign(fooModule, {
foo: function() {
console.log('bar')
}
})
console.log(foo())
All of these attempts fail with
TypeError: Cannot assign to read only property 'foo' of object '[object Module]'
In new Node with modules, is there an expected way to monkey patch modules or parts of a module such that all subsequent imports of that module receive that patch?