+ βββ
+ βββββββ ββββββββ βββββββββββ βββββββ ββββββββββ βββ
+βββββββββββββββββββββββββββββββββββββββββββββββββββ ββββ
+βββββββββββββββββ βββ βββ ββββββ ββββββ ββββββββ
+βββββββββ βββββββββββ βββ ββββββ ββββββ ββββββββ
+βββββββββββββββββββββ βββ βββββββββββββββββββββββ ββββ
+ ββββββββββββββββ βββ βββ βββ βββββββ ββββββββββ βββ
esmock provides native ESM import and globals mocking for unit tests. Use examples below as a quick-start guide, see the descriptive and friendly esmock guide here, or browse esmock's test runner examples.
Note: For versions of node prior to v20.6.0, "--loader" command line arguments must be used with esmock
as demonstrated in the wiki. Current versions of node do not require "--loader".
Note: due to --loader issues, support for ava
and jest
are dropped.
esmock
has the below signature
await esmock(
'./to/module.js', // path to target module being tested
{ ...childmocks }, // mock definitions imported by target module
{ ...globalmocks }) // mock definitions imported everywhere
esmock
examples
import test from 'node:test'
import assert from 'node:assert'
import esmock from 'esmock'
test('package, alias and local file mocks', async () => {
const cookup = await esmock('../src/cookup.js', {
addpkg: (a, b) => a + b,
'#icon': { coffee: 'β', bacon: 'π₯' },
'../src/breakfast.js': {
default: () => ['coffee', 'bacon'],
addSalt: meal => meal + 'π§'
}
})
assert.equal(cookup('breakfast'), 'βπ₯π§')
})
test('full import tree mocks βthird param', async () => {
const { getFile } = await esmock('../src/main.js', {}, {
// mocks *every* fs.readFileSync inside the import tree
fs: { readFileSync: () => 'returned to π² every caller in the tree' }
})
assert.equal(getFile(), 'returned to π² every caller in the tree')
})
test('mock fetch, Date, setTimeout and any globals', async () => {
// https://github.com/iambumblehead/esmock/wiki#call-esmock-globals
const { userCount } = await esmock('../Users.js', {
'../req.js': await esmock('../req.js', {
import: { // define globals like 'fetch' on the import namespace
fetch: async () => ({
status: 200,
json: async () => [['jim','π'],['jen','π']]
})
}
})
})
assert.equal(await userCount(), 2)
})
test('mocks "await import()" using esmock.p', async () => {
// using esmock.p, mock definitions are kept in cache
const doAwaitImport = await esmock.p('../awaitImportLint.js', {
eslint: { ESLint: cfg => cfg }
})
// mock definition is returned from cache, when import is called
assert.equal(await doAwaitImport('cfgπ οΈ'), 'cfgπ οΈ')
// a bit more info are found in the wiki guide
})
test('esmock.strict mocks', async () => {
// replace original module definitions and do not merge them
const pathWrapper = await esmock.strict('../src/pathWrapper.js', {
path: { dirname: () => '/path/to/file' }
})
// error, because "path" mock above does not define path.basename
assert.rejects(() => pathWrapper.basename('/dog.πΆ.png'), {
name: 'TypeError',
message: 'path.basename is not a function'
})
})