Releases: nuxt/test-utils
v4.0.0
4.0.0 is the next major release.
👀 Highlights
We're releasing Nuxt Test Utils v4, with support for Vitest v4. 🚀
Better mocking support
The biggest improvement in this release is how mocking works. Nuxt initialization has been moved from setupFiles to the beforeAll hook (#1516), which means vi.mock and mockNuxtImport calls now take effect before Nuxt starts. This fixes a long-standing issue where mocks for composables used in middleware or plugins wouldn't apply reliably (#750, #836, #1496).
On top of that, mockNuxtImport now passes the original implementation to the factory function (#1552), making partial mocking much more natural:
mockNuxtImport('useRoute', original => vi.fn(original))
it('my test', async () => {
vi.mocked(useRoute).mockImplementation(
(...args) => ({ ...vi.mocked(useRoute).getMockImplementation()!(...args), path: '/mocked' }),
)
const wrapper = await mountSuspended(MyComponent)
expect(wrapper.find('#path').text()).toBe('/mocked')
})registerEndpoint improvements
registerEndpoint now works correctly with query parameters in URLs (#1560), and endpoints registered in setup files are no longer lost when modules reset (#1549).
🚧 Migration
@nuxt/test-utils v4 contains a few breaking changes, almost all related to requiring at least vitest v4 as a peer dependency (if you are using vitest). It replaces vite-node with Vite's native Module Runner and simplifies pool configuration.
This will mean improvements for test performance and mocking, but does require some changes to your test code.
Tip
Most of the changes below are straightforward. The biggest thing to watch out for is code that runs at the top level of a describe block — see below.
Update your dependencies
Update vitest and its companion packages together:
{
"devDependencies": {
- "@nuxt/test-utils": "^3.x",
- "vitest": "^3.x",
- "@vitest/coverage-v8": "^3.x"
+ "@nuxt/test-utils": "^4.0",
+ "vitest": "^4.0",
+ "@vitest/coverage-v8": "^4.0"
}
}Peer dependencies
We've tightened peer dependency ranges. You may need to update some of these:
| Dependency | v3 | v4 |
|---|---|---|
vitest |
^3.2.0 |
^4.0.2 |
happy-dom |
* |
>=20.0.11 |
jsdom |
* |
>=27.4.0 |
@jest/globals |
^29.5.0 || >=30.0.0 |
>=30.0.0 |
@cucumber/cucumber |
^10.3.1 || >=11.0.0 |
>=11.0.0 |
@testing-library/vue |
^7.0.0 || ^8.0.1 |
^8.0.1 |
Later environment setup
This is the change that might require most change in your tests. Because we've moved the nuxt environment setup into beforeAll, this means composables called at the top level of a describe block will fail with [nuxt] instance unavailable.
// Before (worked in vitest v3)
describe('my test', () => {
const router = useRouter() // ran lazily, after environment setup
// ...
})
// After (vitest v4)
describe('my test', () => {
let router: ReturnType<typeof useRouter>
beforeAll(() => {
router = useRouter() // runs after environment setup
})
// ...
})This applies to useRouter(), useNuxtApp(), useRoute(), and any other Nuxt composable or auto-import.
Tip
If you only need the value within individual tests, beforeEach or directly within the test works too.
Stricter mock exports
If you use vi.mock with a factory function, accessing an export that the factory doesn't return will now throw an error instead of silently returning undefined.
// Before: accessing `bar` would silently return undefined
vi.mock('./module', () => ({ foo: 'mocked' }))
// After: accessing `bar` throws
// Fix: use importOriginal to include all exports
vi.mock('./module', async (importOriginal) => ({
...await importOriginal(),
foo: 'mocked',
}))Note
If you're mocking a virtual module (like #build/nuxt.config.mjs) where importOriginal can't resolve the real module, you might need to explicitly list all accessed exports in your mock factory.
Other changes
For the full list, see the vitest v4 migration guide.
👉 Changelog
🚀 Enhancements
- deps:
⚠️ Upgrade to vitest v4 (#1481) - deps:
⚠️ Drop official support for older versions of test runners + dom environments (31fdc262a) - runtime-utils: Pass original to
mockNuxtImportfactory (#1552) - runtime:
⚠️ Change nuxt start timing tobeforeAllhook (#1516) - e2e: Support setup and teardown timeouts in setupBun (#1578)
🩹 Fixes
- runtime: Handle optional chaining vueWrapper plugin installed check (#1547)
- runtime-utils: Keep endpoints from registerEndpoint in setup file (#1549)
- runtime-utils: Support
registerEndpointwith query params (#1560) - runtime-utils: Avoid local variable in mockNuxtImport macro (#1564)
- runtime-utils: Add missing
nextTickimport (#1563) - Pin h3-next to patch (1ff3bbb91)
- playwright: Bump windows timeout (63e39b7c9)
- config: Respect include options in non nuxt environment simple setup (#1570)
💅 Refactors
- module: Use
@nuxt/devtools-kitfor devtools hooks (426e0b537) - runtime: Remove unnecessary querySelector (#1577)
📖 Documentation
- Add nuxt.care health badge (1499a48de)
🏡 Chore
- Allow changelog update util to return major bump (9e86cadab)
- Make
app-vitestfollow advised setup guidelines (#1542) - Update lockfile (6d798b5e1)
- config: Migrate Renovate config (#1568)
- Add test utils setup to
.nuxtrc(b4021dee4)
✅ Tests
- Avoid running root test script twice (44f6bd396)
⚠️ Breaking Changes
- deps:
⚠️ Upgrade to vitest v4 (#1481) - deps:
⚠️ Drop official support for older versions of test runners + dom environments (31fdc262a) - runtime:
⚠️ Change nuxt start timing tobeforeAllhook (#1516)
❤️ Contributors
- Yoshihiro Yamaguchi (@yamachi4416)
- Daniel Roe (@danielroe)
- Adam DeHaven (@adamdehaven)
v3.23.0
3.23.0 is the next minor release.
👉 Changelog
🚀 Enhancements
🩹 Fixes
- e2e: Ensure
$fetchis not typed asany(1f4754ea9)
🏡 Chore
- Remove leftover
console.log(aef693340)
✅ Tests
- Add cleanup to resolve-config tests (#1537)
🤖 CI
- Prepare build environment in autofix workflow (2c0864ed6)
❤️ Contributors
- Daniel Roe (@danielroe)
- yamachi4416 (@yamachi4416)
v3.22.0
3.22.0 is the next minor release.
👉 Changelog
🚀 Enhancements
- runtime-utils: Unify logic of mount + render helpers (#1522)
- module: Run
vitestin separate process (#1524) - runtime-utils: Allow skipping initial route change (fd77ec066)
- runtime: Skip route sync emulation when
NuxtPageexists (#1530)
🔥 Performance
- module: Skip nuxt-root stub plugin when building (#1512)
🩹 Fixes
- runtime-utils: Reject promise on error render + mount helpers (#1503)
- runtime-utils: Support new
.syncmethod for syncing route (1148c3cf1) - e2e: Always override global env options with inline options (c8f881b3d)
- runtime-utils: Avoid missing render warn on reject render + suspend helpers (#1520)
- e2e: Use
server.depsrather thandeps(2b3c86921) - config: Also call
sync()in initial setup (ec555192c) - module: Use
devtools:beforehook instead of direct config check (#1532) - config: Do not override vitest root with nuxt
rootDir(#1531)
💅 Refactors
- runtime-utils: Do not export
addCleanup(86b4998bb) - module: Extract nuxt environment options plugin (5ada22a9f)
📖 Documentation
- Fix link to module authors testing guide (#1511)
🏡 Chore
- Use
nuxtcli command in preference tonuxi(838ed8b6a) - Add
@vitest/uito example (ffaccd8a1) - Fix some example
package.jsonnames (417102718) - Skip bun test (c19a659d3)
- Ignore root interfaces (9739057ae)
✅ Tests
- Use local kit version for module (79f1e14d5)
- Add
defaultLocalein i18n test (059988fc3) - Avoid definePageMeta compiler-hint warning (#1523)
🤖 CI
- Run
knipon pull requests (a94098671)
❤️ Contributors
- Daniel Roe (@danielroe)
- yamachi4416 (@yamachi4416)
- Maurice Putz (@Shooteger)
v3.21.0
3.21.0 is the next minor release.
👉 Changelog
🚀 Enhancements
- runtime-utils: Support rerender behavior in renderSuspended (#1466)
- runtime-utils: Support
onceoption inregisterEndpoint(#1475) - runtime-utils: Support css modules in mount + render helpers (#1464)
- runtime-utils: Pass app context across in mount + render helpers (#1477)
- runtime-utils: Support mocked target arguments in mockNuxtImport (#1492)
🩹 Fixes
- runtime: Remove redefinition of
$fetch.create(#1471) - runtime-utils: Pass non-enumerable
globalPropertiesin mount + render helpers (#1476) - module: Include vitest config in node project (#1497)
- runtime-utils: Improve mount + render helpers (#1483)
- Revert to
@nuxt/kitv3 for bridge support (#1498)
🏡 Chore
- Move built dep configuration -> workspace file (d936cb465)
- Update pnpm to 10.21 and enable trust policy (ed6ff050d)
- Revert pnpm trust policy and restore provenance action (b034f0a5e)
- Remove spurious
globbydependency (eba19d16b) - Remove export (2a88683bd)
- Remove
@nuxt/kitfrom peer dependencies (b80ca5ea8) - Add back
@nuxt/kitas peer dep (5c126e1af) - Bump vite-node to v5 (3322919c2)
🤖 CI
- Rebuild better-sqlite3 on windows (9fdaf3824)
❤️ Contributors
- Daniel Roe (@danielroe)
- yamachi4416 (@yamachi4416)
- Ryota Watanabe (@wattanx)
v3.20.0
3.20.0 is the next minor release.
👉 Changelog
🚀 Enhancements
- runtime-utils: Automatic ref unwrapping for
wrapper.vm(#1405) - runtime: Allow
registerEndpointto work with native fetch (#1415) - runtime: Add
scopedoption to cleanup components (#1389)
🩹 Fixes
- runtime-utils: Capture events emitted before the first render (#1353)
- runtime-utils: Add missing import (#1372)
- e2e: Detect nuxt config files in
.configfolder (#1381) - e2e: Bump windows teardown timeout to 60s (9f1f712da)
- runtime: Allow
registerEndpointto work with$fetch.create(#1403) - Handle optional chaining for imports in
setupImportMockingfunction (#1433) - vitest: Support
virtualConsole.forwardToinjsdom(6b4076a04) - vitest: Call
window.closeon jsdom teardown (25b87eef3) - vitest: Stub
IntersectionObserverin teardown (230dd240a)
📖 Documentation
🏡 Chore
- Switch to npm trusted publishing (3a1f194fb)
- deps-dev: Bump happy-dom from 19.0.2 to 20.0.0 (#1441)
- Relax upper peerDependency ranges (4676f4bf3)
- Add test script (3126fa243)
✅ Tests
- Add example tests for nuxt ui (#1396)
🤖 CI
- Do not fail matrix if one os fails (7d2969e29)
- Add read contents permission (782119685)
- Run release tasks on latest node version (fb2007b33)
- Add provenance action to check for downgrades in provenance (10288633c)
❤️ Contributors
- Daniel Roe (@danielroe)
- Mike Laumann Bellika (@MikeBellika)
- yamachi4416 (@yamachi4416)
- Vasily Kuzin (@ExEr7um)
- dependabot[bot] (@dependabot[bot])
- Toshiki Yoshioka (@ytoshiki)
- Jess (@JessicaSachs)
- Yizack Rangel (@Yizack)
- Ingo Renner (@irnnr)
- Tomina (@Thomaash)
v3.19.2
3.19.2 is the next patch release.
Timetable: 1 July
👉 Changelog
🩹 Fixes
- config: Add missing mocks for vue-devtools (#1321)
- runtime-utils: Prevent event duplication (#1328)
- config: Include tests without
.nuxt.extension (#1311) - deps: Drop
@nuxt/schemadependeny (fa3a99b4) - config: Use 'projects' for
vitest>= v3.2 (#1344) - module: Use user
viteversion to merge config (#1345) - runtime-utils: Handle computed defined using an object (#1342)
🏡 Chore
- Prefer
nuxtovernuxi(#1310) - Pin node types (93921643)
- Do not include dev-deps in
engines.nodecalculation (2f74359b) - Add type assertions for indexed access (51b4a4e3)
- Update installed-check flag (2b97d885)
✅ Tests
- Update stub name for nuxt v4 (e7b07843)
- Satisfy typescript (fb0dea24)
- Update cucumber test for nuxt v4 welcome screen template (8ec7782f)
- Simplify test (90278bac)
- Update workspace example (02f9b0a0)
- Make browser tests forward-compat with v4 (574ea5f9)
🤖 CI
- Remove forced corepack installation (bf19bd3a)
- Run
knip(819aeacc) - Prepare environment before knipping (ec7d8ddd)
❤️ Contributors
- Daniel Roe (@danielroe)
- Tomina (@Thomaash)
- lutejka (@lutejka)
- J-Michalek (@J-Michalek)
v3.19.1
👉 Changelog
🩹 Fixes
- config: Upgrade nuxt devtools + disable vue devtools (#824)
- module: Import
defineConfigfrom vite (467886ea)
🏡 Chore
- Don't ignore
@nuxt/devtoolsupgrade (3ae47b43)
❤️ Contributors
- Daniel Roe (@danielroe)
v3.19.0
👉 Changelog
🚀 Enhancements
- config: Support vitest workspaces with
defineVitestProject(#1258) - config: Add nuxt environment browser-testing support (#1294)
🩹 Fixes
- config: Use
UserConfigrather thanInlineConfigfromvite(e2a1598b)
💅 Refactors
- Rename
core->e2einternally (a81c4498)
✅ Tests
- Set
environment: 'nuxt'for browser testing example (96769e55) - Add browser mode tests for nuxt/content components (#1284)
❤️ Contributors
- Jess (@JessicaSachs)
- Daniel Roe (@danielroe)
v3.18.0
🚀 Enhancements
🩹 Fixes
- vitest-environment: Respect custom
app.baseURLin manifest path (#1213) - runtime-utils: Wrap
WrapperComponentdefault slot in function (#1244)
💅 Refactors
- Rename
setuphook tobeforeAllfor clarity (#1221)
📖 Documentation
- Consistent URL formatting (#1217)
✅ Tests
- Update module example (1b42cef1)
- Await reject promise (1ecbb0e1)
- Reorder test options object (086415b0)
- Use
tinyglobby(6f16c6dd)
❤️ Contributors
- Jess (@JessicaSachs)
- Daniel Roe (@danielroe)
- m0nch1 (@m0nch1)
- Bobbie Goede (@BobbieGoede)
v3.17.2
3.17.2 is the next patch release.
Timetable: to be announced.
👉 Changelog
🩹 Fixes
- vitest-environment: Migrate from unenv -> node-mock-http (#1179)
🏡 Chore
- Remove contents sqlite (54cb15be)
❤️ Contributors
- Daniel Roe (@danielroe)