I want to mock a node's built-in function require.resolve
in jest test suite. Here a working example of a problem on repl.it and the code itself:
Test subject (as an example):
const requirer = () => {
try {
return require.resolve('./add')
} catch (error) {
console.error('failed to find a module')
}
}
module.exports = requirer
Test suite:
const requirer = require('./requirer')
describe('attempt to mock require.resolve', () => {
it('does not work', () => {
require.resolve = jest.fn(arg => `./${arg}`)
console.log(
'is require.resolve mocked',
jest.isMockFunction(require.resolve)) // will say true
requirer()
expect(require.resolve).toHaveBeenCalledTimes(1)
expect(require.resolve).toBeCalledWith('')
})
})
Inside of a test suite declaration everything is OK (see an output of a jest.isMockFunction(require.resolve)
) and mock works. But for a test subject require.resolve
remains with original functionality.
Due to this issue, this isn't pure unit test.
If I, for example, mock process.exit
everything works as expected.
You can create a namespace that you export as the default object and call b using the namespace. This way, when you call jest. mock it will replace the b function on the namespace object. const f = require('./f'); jest.
Mock functions allow you to test the links between code by erasing the actual implementation of a function, capturing calls to the function (and the parameters passed in those calls), capturing instances of constructor functions when instantiated with new , and allowing test-time configuration of return values.
Using with ES module imports But often you need to instruct Jest to use a mock before modules use it. For this reason, Jest will automatically hoist jest. mock calls to the top of the module (before any imports).
Mocking is a technique to isolate test subjects by replacing dependencies with objects that you can control and inspect. A dependency can be anything your subject depends on, but it is typically a module that the subject imports.
So, not a perfect solution, but it is simpler to inject (DI) require.resolve into
const requirer = (resolver) => {
try {
return resolver('./add')
} catch (error) {
console.error('failed to find a module')
}
}
module.exports = requirer
now in a test suite passing down mocked version of a require.resolve
works as expected
const requirer = require('./requirer')
describe('attempt to mock require.resolve', () => {
it('works', () => {
require.resolve = jest.fn(arg => `./${arg}`)
console.log(
'is require.resolve mocked',
jest.isMockFunction(require.resolve)) // will say true
requirer(require.resolve)
expect(require.resolve).toHaveBeenCalledTimes(1)
// expect(require.resolve).toBeCalledWith('')
})
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With