oven-sh / bun

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one
https://bun.sh
Other
73.2k stars 2.68k forks source link

Implement the Ability to Revert the Mocking of Modules #7376

Open constraintAutomaton opened 9 months ago

constraintAutomaton commented 9 months ago

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.

chlorophant commented 8 months ago

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

Jarred-Sumner commented 8 months ago

For now, try the following:

import {jest} from 'bun:test';

jest.restoreAllMocks();
grant-heath commented 7 months ago

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

cwqt commented 5 months ago

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
coodoo commented 3 months ago

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? 😉