N
Nuxt•2w ago
AxelSorensen

Nuxt Middleware testing

Is there any way to test middleware (specifically redirecting from unauthorized routes based on a user attribute. I am working with Nuxt Test Utils in Nuxt 4.0.3 In my middleware I have: const { user } = useAuth(); if (isAdminRoute && !ADMINS.includes(user.value.email)) { return navigateTo("/"); } Now in my test file I want to test whether non admin users get redirected. I tried mocking useAuth as mentioned in the docs, but it doesnt seem to register on middleware import { vi } from 'vitest' import { mockNuxtImport } from '@nuxt/test-utils/runtime' const { useAuthMock } = vi.hoisted(() => { return { useAuthMock: vi.fn(() => { return { user: { email: 'dwadwadwa' } } }) } }) mockNuxtImport('useAuth', () => { return useAuthMock }) // Then, inside a test useAuthMock.mockImplementation(() => { return { user: { email: 'somethingelse@example.com' } } }) ` Is there anyway to do this, I would love to test my components and routes with different users? Wondering if this is a bug in 4.0.3 or how its supposed to be. Thanks in advancešŸ™
3 Replies
kapa.ai
kapa.ai•2w ago
Hi @AxelSorensen. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Yes, you can test Nuxt middleware that uses auto-imported composables like useAuth by mocking them with mockNuxtImport from @nuxt/test-utils/runtime. Your approach is correct and aligns with the official documentation and community recommendations. Here’s a summary of the correct approach: 1. Use mockNuxtImport to mock auto-imported composables
This is necessary because Nuxt auto-imports composables, so direct mocking of the module may not work. Instead, you should use mockNuxtImport to intercept the auto-import. 2. Use vi.hoisted for mock functions
This ensures your mock is available before the middleware is loaded, as mocks are hoisted. 3. Change the mock implementation per test as needed
You can update the mock’s return value to simulate different user states. Here’s a minimal working example based on your scenario:
import { vi } from 'vitest'
import { mockNuxtImport } from '@nuxt/test-utils/runtime'

// Hoist the mock so it's available before middleware is loaded
const { useAuthMock } = vi.hoisted(() => {
return {
useAuthMock: vi.fn(() => {
return { user: { email: 'notadmin@example.com' } }
})
}
})

// Mock the auto-imported composable
mockNuxtImport('useAuth', () => useAuthMock)

// In your test, you can change the implementation as needed
useAuthMock.mockImplementation(() => {
return { user: { email: 'admin@example.com' } }
})

// Now run your middleware and assert the redirect
import { vi } from 'vitest'
import { mockNuxtImport } from '@nuxt/test-utils/runtime'

// Hoist the mock so it's available before middleware is loaded
const { useAuthMock } = vi.hoisted(() => {
return {
useAuthMock: vi.fn(() => {
return { user: { email: 'notadmin@example.com' } }
})
}
})

// Mock the auto-imported composable
mockNuxtImport('useAuth', () => useAuthMock)

// In your test, you can change the implementation as needed
useAuthMock.mockImplementation(() => {
return { user: { email: 'admin@example.com' } }
})

// Now run your middleware and assert the redirect
This pattern is confirmed in the Nuxt documentation and community answers. If your mock is not being picked up, double-check that: - The mock is defined before the middleware is loaded. - You are using the correct composable name as auto-imported by Nuxt. - You are running your tests in the Nuxt environment (not plain Node). References:
- Nuxt Testing: mockNuxtImport - Stack Overflow: Mocking auto-imported composables in Nuxt - Conflict with End-To-End Testing If you still encounter issues, ensure you are using the latest version of @nuxt/test-utils and that your test files are set up to run in the Nuxt environment. There is no indication in the knowledge sources that this is a bug in Nuxt 4.0.3; the described approach is the recommended and supported way to mock auto-imported composables for middleware testing. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai•2w ago
<@558317900943982593> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
AxelSorensen
AxelSorensenOP•2w ago
Also is there a way to test the Nuxt API routes, when I try calling a service which fetches an api route I get: [POST] "/api/market/detect_markets": 404 Cannot find any path matching /api/market/detect_markets. Even though I use await setup({}) in the test file I was able to use $fetch from the test file to fetch the api routes however I was not able to make all the fetches from within my services use this $fetch from nuxt-test-utils This goes for plugins as well, is there a way to mock them?

Did you find this page helpful?