Skip to content

Provide disposable APIs for releasing mocks #8425

@kirkwaiblinger

Description

@kirkwaiblinger

Clear and concise description of the problem

It's easy to forget to release mocks. For example, the following code mocking the node:path module pollutes subsequent test cases by forgetting to release the mock.

import { describe, expect, vi, it } from 'vitest';

describe('pollution', () => {
  it('mocks a module', async () => {
    vi.doMock(import('node:path'), async (importActual) => {
      const pathActual = await importActual();
      return {
        ...pathActual,
        default: 'mocked!'
      }
    })

    const path = await import('node:path');

    expect(path.default).toBe('mocked!');
  })

  it('should not be mocked anymore', async () => {
    const path = await import('node:path');
    expect(path.default).not.toBe('mocked!'); // fails; polluted by other test case
  });
})

Suggested solution

It would be highly ergonomic to release mocks by providing a disposable API that releases the mock

import { describe, expect, vi, it } from 'vitest';

describe('no pollution', () => {
  it('mocks a module', async () => {
    using _temporary_mock = vi.disposableMock(import('node:path'), async (importActual) => {
      const pathActual = await importActual();
      return {
        ...pathActual,
        default: 'mocked!'
      }
    })

    const path = await import('node:path');
  
    expect(path.default).toBe('mocked!');
  })

  it('should not be mocked anymore', async () => {
    const path = await import('node:path');
    expect(path.default).not.toBe('mocked!');
  });
})

Alternative

One can either

  • keep track of all mocked modules, and use a beforeEach/afterEach with vi.doUnmock('node:path');
  • use try ... finally to call vi.doUnmock('node:path') after calling vi.doMock('node:path');

These both rely on non-local code to clean up the mock state, whereas using would localize all information to the declaration of the mock

Additional context

using is available out of the box in current versions of node.

keywords: explicit resource management

Validations

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    Status

    Approved

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions