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
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
This is necessary because Nuxt auto-imports composables, so direct mocking of the module may not work. Instead, you should use
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: 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
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 composablesThis 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 functionsThis 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: 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:
----------------------<@558317900943982593> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
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?