bun icon indicating copy to clipboard operation
bun copied to clipboard

Implement the Ability to Revert the Mocking of Modules

Open constraintAutomaton opened this issue 1 year ago • 2 comments

What is the problem this feature would solve?

In the current Bun test package, it is possible to mock a whole modules using the function mock.module (I don't think this feature is documented...). But it doesn't seem like it is possible to revert to the original implementation. I think in multiple situations this feature is needed and popular frameworks like Jest, who seem to be an inspiration for the test package of Bun, implement it.

What is the feature you are proposing to solve the problem?

A mock.revertAllMock function and an object return from the mock.module function with a method to revert to the specific module to its original implementation.

What alternatives have you considered?

I don't have an other idea.

constraintAutomaton avatar Nov 30 '23 07:11 constraintAutomaton

Additionally mocked modules will conflict with other testfiles that need to mock the same module

chlorophant avatar Jan 22 '24 06:01 chlorophant

For now, try the following:

import {jest} from 'bun:test';

jest.restoreAllMocks();

Jarred-Sumner avatar Jan 22 '24 06:01 Jarred-Sumner

@Jarred-Sumner jest.restoreAllMocks() does not work for me.

grant-heath avatar Feb 16 '24 17:02 grant-heath

This was also affecting me, as a work around I settled on getting all the tests files & running them in separate bun test runs.

find . -path "*test.ts" | xargs -L 1 bun test

cwqt avatar Apr 15 '24 13:04 cwqt

Found a working solution by using delete require.cache[] to reset mocked modules after each test case, confirmed working across multiple test files and cases. Detailed steps below.


// 1. placeholder to persist mocked modules
globalThis.mocked = []

// 2. do the mocking
const spied = spyOn(require(`foo_module`), `bar_fn`)
spied.mockReturnValueOnce = `response 1`
spied.mockReturnValue = `response default`

// 2.1. save the mocked module name so that it can be restored later
globalThis.mocked.push(`foo_module`)

// 3. after each test case, restore the mocked module
globalThis.mocked.forEach(name => {
  delete require.cache[require.resolve(name)]
})

@Jarred-Sumner might as well consider implementing something similar to delete require.cache[] in bun as a quick solution to this issue? 😉

coodoo avatar Jun 06 '24 00:06 coodoo