Help: Testing Nuxt API Routes Using serverSupabaseServiceRole and serverSupabaseUser with Vitest #503
Replies: 3 comments
-
|
I'm also dealing with this right now, and haven't found a good solution yet (granted, I've only been working on it today). But the fact that the supabaseServerClient needs the Nitro request event is weird to me. I understand that it provides all the other benefits of supabase, but that means that I'm having to engineer my Use Cases and my Repositories to all accept nitro events as parameters, which creates tight coupling. Even the serverSupabaseServiceRole requires the event, but it's not doing row level security. Why does it need access to the server event? https://supabase.nuxtjs.org/services/serversupabaseservicerole |
Beta Was this translation helpful? Give feedback.
-
|
Testing server routes that depend on serverSupabaseUser and serverSupabaseServiceRole requires mocking the H3 event and the module internals. There is no official test-utils helper for this yet, so the approach is to mock the imports at the module level. In your test file: import { vi, describe, it, expect, beforeEach } from "vitest" // Mock the module before any imports that use it import { serverSupabaseUser, serverSupabaseServiceRole } from "#supabase/server" // Create a minimal H3 event mock describe("your route", () => { it("returns data for authenticated user", async () => { The critical point is that vi.mock("#supabase/server") must appear before any import of the route handler. Vitest hoists vi.mock calls but the path alias #supabase/server needs to be configured in your vitest.config.ts resolve.alias section. |
Beta Was this translation helpful? Give feedback.
-
|
The key is to mock the virtual module path with vi.mock using a factory function placed at the top level of the test file. Vitest hoists vi.mock calls before imports, so they need to be at the top level and not inside describe or beforeEach. vi.mock("#supabase/server", () => ({
serverSupabaseUser: vi.fn(),
serverSupabaseServiceRole: vi.fn(),
}))Then in each test or in beforeEach, set the resolved values: import { serverSupabaseUser, serverSupabaseServiceRole } from "#supabase/server"
beforeEach(() => {
vi.mocked(serverSupabaseUser).mockResolvedValue({
id: "test-user-id",
email: "test@example.com",
})
vi.mocked(serverSupabaseServiceRole).mockReturnValue({
from: vi.fn().mockReturnThis(),
select: vi.fn().mockReturnThis(),
eq: vi.fn().mockReturnThis(),
single: vi.fn().mockResolvedValue({ data: { id: 1 }, error: null }),
})
})The virtual module alias #supabase/server resolves to the module installed in node_modules. Vitest resolves these aliases through your nuxt.config.ts vite settings, so make sure your vitest.config.ts either extends the Nuxt vite config or has the same alias defined. If you are using @nuxt/test-utils, calling setup() at the top of your test suite initializes the Nuxt context and alias resolution automatically. One note: if serverSupabaseServiceRole returns a synchronous client (not a promise), use mockReturnValue rather than mockResolvedValue for it. For serverSupabaseUser, use mockResolvedValue since it is async. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi everyone,
I’m currently writing tests for Nuxt server API routes using Vitest, and I’m having trouble mocking the Supabase utilities provided by #supabase/server — specifically serverSupabaseUser(event) and serverSupabaseServiceRole(event).
Despite searching extensively, I haven’t found any clear examples or official documentation on how to test Nuxt routes that depend on these functions. The serverSupabaseUser is used to get the authenticated user, and serverSupabaseServiceRole gives a service client for queries. Both are deeply integrated into route logic, so I need a way to mock or stub them to write proper unit tests.
Example route I’m testing
Here’s a simplified version of the route handler (in server/api/accounts/index.ts):
What I’ve tried
What I need help with
⸻
Thanks in advance! 🙏
If I find a solution, I’ll be sure to post it here for others.
Beta Was this translation helpful? Give feedback.
All reactions