Skip to content

Commit b12315c

Browse files
make doMock() return a disposable
1 parent de4e6aa commit b12315c

File tree

3 files changed

+58
-4
lines changed

3 files changed

+58
-4
lines changed

docs/api/vi.md

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,11 +179,11 @@ If there is no `__mocks__` folder or a factory provided, Vitest will import the
179179
function doMock(
180180
path: string,
181181
factory?: MockOptions | MockFactory<unknown>
182-
): void
182+
): Disposable
183183
function doMock<T>(
184184
module: Promise<T>,
185185
factory?: MockOptions | MockFactory<T>
186-
): void
186+
): Disposable
187187
```
188188

189189
The same as [`vi.mock`](#vi-mock), but it's not hoisted to the top of the file, so you can reference variables in the global file scope. The next [dynamic import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import) of the module will be mocked.
@@ -229,6 +229,26 @@ test('importing the next module imports mocked one', async () => {
229229
})
230230
```
231231

232+
::: tip
233+
In environments that support [Explicit Resource Management](https://github.com/tc39/proposal-explicit-resource-management), you can use `using` instead of `const` to automatically call [`vi.doUnmock()`](#vi-dounmock) on the mocked module when the containing block is exited. This is especially useful when mocking a dynamically imported module for a single test case.
234+
235+
```ts
236+
it('uses a mocked version of my-module', () => {
237+
using _mockDisposable = vi.doMock('my-module')
238+
239+
const myModule = await import('my-module') // mocked
240+
241+
// my-module is restored here
242+
})
243+
244+
it('uses the normal version of my-module again', () => {
245+
const myModule = await import('my-module') // not mocked
246+
})
247+
```
248+
:::
249+
250+
::: tip
251+
232252
### vi.mocked
233253

234254
```ts

packages/vitest/src/integrations/vi.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,11 +220,13 @@ export interface VitestUtils {
220220
* Mocking algorithm is described in [documentation](https://vitest.dev/guide/mocking/modules).
221221
* @param path Path to the module. Can be aliased, if your Vitest config supports it
222222
* @param factory Mocked module factory. The result of this function will be an exports object
223+
*
224+
* @returns A disposable object that calls {@link doUnmock()} when disposed
223225
*/
224226
// eslint-disable-next-line ts/method-signature-style
225-
doMock(path: string, factory?: MockFactoryWithHelper | MockOptions): void
227+
doMock(path: string, factory?: MockFactoryWithHelper | MockOptions): Disposable
226228
// eslint-disable-next-line ts/method-signature-style
227-
doMock<T>(module: Promise<T>, factory?: MockFactoryWithHelper<T> | MockOptions): void
229+
doMock<T>(module: Promise<T>, factory?: MockFactoryWithHelper<T> | MockOptions): Disposable
228230
/**
229231
* Removes module from mocked registry. All subsequent calls to import will return original module.
230232
*
@@ -617,6 +619,14 @@ function createVitest(): VitestUtils {
617619
)
618620
: factory,
619621
)
622+
623+
const rv = {} as Disposable
624+
if (Symbol.dispose) {
625+
rv[Symbol.dispose] = () => {
626+
_mocker().queueUnmock(path, importer)
627+
}
628+
}
629+
return rv
620630
},
621631

622632
doUnmock(path: string | Promise<unknown>) {

test/core/test/do-mock.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,27 @@ test('the second doMock can override the first doMock', async () => {
3030

3131
expect(incrementWith20(1)).toBe(21)
3232
})
33+
34+
test('doMock works with using', async () => {
35+
vi.doUnmock('./fixtures/increment')
36+
37+
{
38+
const { increment: incrementWith1 } = await import('./fixtures/increment')
39+
expect(incrementWith1(1)).toBe(2)
40+
}
41+
42+
{
43+
using _incrementMock = vi.doMock('./fixtures/increment', () => ({
44+
increment: (num: number) => num + 10,
45+
}))
46+
47+
const { increment: incrementWith10 } = await import('./fixtures/increment')
48+
49+
expect(incrementWith10(1)).toBe(11)
50+
}
51+
52+
{
53+
const { increment: incrementWith1 } = await import('./fixtures/increment')
54+
expect(incrementWith1(1)).toBe(2)
55+
}
56+
})

0 commit comments

Comments
 (0)