Five things that break when you move from Jest to Vitest
Vitest advertises a Jest-compatible API, and it delivers. describe , test , expect , toHaveBeenCalledWith — all identical. Which is why the five things that aren't compatible are so disorienting: the suite mostly runs, and then a handful of files fail for reasons the error messages don't explain. 1. Globals are opt-in Jest injects describe and expect into the global scope. Vitest doesn't, by…
Moving from Jest to Vitest can present challenges due to five incompatibilities that break certain functionalities.
First, Vitest's global scope differs from Jest's. While Jest automatically injects describe, expect, and other functions into the global scope, Vitest requires explicit opt-in. This is controlled through the `globals` property in the Vitest configuration file. Migrating to this setup requires a separate commit, and mixing it with other changes can make the diff unreviewable.
Second, Vitest does not use `moduleNameMapper` like Jest does. Path aliases are moved to Vite's resolver instead. While this simplifies configuration, it means that alias settings in Vitest will also affect your bundle. It's crucial to verify these settings once they're migrated.
Third, Vitest handles `jest.mock` differently than Jest does. Vitest's hoisting behavior affects how variables are closed over. This requires adjusting the way mocks are set up - using Vitest's `vi.hoisted` method instead of Jest's `jest.mock`. The naming conventions for mocks that were commonly used in Jest also have no special handling in Vitest, so they won't have the same effect.
Fourth, `restoreMocks` and `clearMocks` in Vitest behave differently compared to Jest. In Jest, `restoreMocks` resets both calls and instances between tests, while `clearMocks` does the same plus resets the implementation to undefined. In Vitest, `restoreMocks` does the same as Jest, but `clearMocks` only resets calls and instances, leaving implementations unaffected. Failing to account for these differences can lead to unexpected behavior, such as spies created in one test still being installed in subsequent tests.
Last, Vitest requires an environment to be specified per file, and it doesn't bundle a DOM implementation like jsdom. To use a DOM implementation, install jsdom and then set it either globally or per file using the `@vitest-environment` comment. Mixing `node-environment` and `jsdom` tests in the same run can cause confusion, as Vitest does not support this combination.
To tackle these issues, it's recommended to first run the Vitest suite without making any changes. Then, start by migrating aliases, followed by mocks, and finally setting the environment correctly. This order helps isolate the source of each batch of failures. While the migration does require effort, it's manageable and not a complete rewrite. Most of a suite's functionality, like assertions, matchers, and coverage output, remains functional.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.