<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=1063935717132479&amp;ev=PageView&amp;noscript=1 https://www.facebook.com/tr?id=1063935717132479&amp;ev=PageView&amp;noscript=1 "> Bitovi Blog - UX and UI design, JavaScript and Frontend development
Loading

React |

More Mocks! Mocking Modules in Vitest

Improve your testing strategies by learning how to mock modules in Vitest. You'll mock all (or part) of imported modules and use TypeScript to catch errors.

Rich McNeary

Rich McNeary

Twitter Reddit

As of 2024, Vitest is all the rage for testing. But can we apply what we learned about mocking modules in Jest to Vitest? Absolutely!

This post expands on Mocking Modules in Jest Tests. The Vite testing environment shares many of the same API interfaces as Jest, so start with Mocking Modules in Jest Tests for detailed information about mocking functions, interfaces, and React components.

The good news is that almost every API method in Jest is available in vitest. The one small, non-trivial, difference involves importing modules for mocking.

Module Imports

Let’s get right to the point—in any place where you are using the actual module, you will need to use importActual and mark the mock factory function as async.

vi.mock('./navigation', async () => {
  const actualNavigationModule = await vi.importActual('./navigation');
});

Now that I’ve spoiled the ending, allow me to take a step back and explain why you need to use importActual in the first place.

To review quickly, in Jest, if you want to import a module and mock a single function, the code looks like the following: The actual navigation module is imported inside the mock factory function, all the actual methods are spread on the factory’s result, and a mocked calculateRoute method is provided with a different implementation to be used in tests.

// Jest - spaceship.spec.js

let mockErrorId;
vi.mock('./navigation', () => {
  const actualNavigationModule = jest.requireActual("./navigation");

  return {
    ...actualNavigationModule,
    calculateRoute: (from, to, starDateTimeSeconds, setLastError) => {
      const err = actualNavigationModule.errorIdToErrorData(mockErrorId);
      setLastError(err);
    },
  };
});

In Vitest, importing a module uses an async pattern. When you use Vitest’s importActual method, it returns a Promise that resolves to the module. The asynchronicity of the importActual method seems like a challenge, but it’s simply solved by making the mock factory function async.

// vitest - spaceship.spec.js

let mockErrorId;
vi.mock('./navigation', async () => { // <- now async
  // Use the `importActual` method and await it.
  const actualNavigationModule = await vi.importActual('./navigation');

  return {
    ...actualNavigationModule,
    calculateRoute: (from, to, starDateTimeSeconds, setLastError) => {
      const err = actualNavigationModule.errorIdToErrorData(mockErrorId);
      setLastError(err);
    },
  };
});

Hooray! Now your Vitest tests complete successfully using the mock code!

Get TypeScript working

Now you’ll want to switch to using TypeScript for type information and checking while writing tests. The default resolved result type of importActual is ESModuleExports. This is problematic if you want to access a specific method from the imported module, as you’ll encounter an error like:

'actualNavigationModule.errorIdToErrorData' is of type 'unknown'. ts(18046)

To solve the error you need to type the result of importActual.

// vitest - spaceship.spec.ts

import type * as NavigationModule from './navigation';

vi.mock('./navigation', async () => {
  const actualNavigationModule = await vi.importActual<typeof NavigationModule>(
    './navigation'
  );
});

Note that in the above code, you’ve imported the NavigationModule using the type keyword, then applied it using typeofas the result type of importActual. Now you have access to type information for the navigation module.

Now you can mock modules in both Jest and Vitest! 🎉

Once again, if you’re looking for complete and detailed information on different strategies and methods to mock modules in Jest and Vitest, please see the Mocking Modules in Jest Tests post.

Feeling mocked by mocks?

Drop into our Community Discord for help. Our frontend development consultants are always available to lend a hand. Whether you’re working on testing for a small project or building an enterprise application, we can help you find your way.

Join our Discord