How to mock useSupabaseClient composable?
#363
Replies: 3 comments
|
The last one could be an answer indeed. |
|
The standard approach is mockNuxtImport from @nuxt/test-utils, which intercepts the auto-import before it reaches Vitest. Here is a working pattern: import { mockNuxtImport } from "@nuxt/test-utils/runtime" const mockSelect = vi.fn().mockResolvedValue({ data: [], error: null }) mockNuxtImport("useSupabaseClient", () => { The key points:
If you are not using @nuxt/test-utils (running Vitest outside the Nuxt test environment) you can also do a manual module mock: vi.mock("#imports", () => ({ This works when you are mounting components with mountSuspended. |
|
The mockNuxtImport function from @nuxt/test-utils is the recommended approach for mocking Nuxt auto-imported composables, and useSupabaseClient falls into that category. The factory you pass to mockNuxtImport should return the composable itself (a function), not the mock return value directly. The inner function is what useSupabaseClient becomes in your component, so calling useSupabaseClient() calls that inner function: import { mockNuxtImport } from "@nuxt/test-utils/runtime"
mockNuxtImport("useSupabaseClient", () => {
return () => ({
auth: {
onAuthStateChange: vi.fn().mockReturnValue({
data: { subscription: { unsubscribe: vi.fn() } },
}),
},
realtime: {
removeAllChannels: vi.fn(),
},
rpc: vi.fn().mockResolvedValue({ data: null, error: null }),
})
})This call must be at the top level of the test file, outside of describe and beforeEach, because mockNuxtImport wraps vi.mock which Vitest hoists before imports. If you need different return values per test, call vi.mocked inside the test after the top-level mock is in place: it("handles error", async () => {
vi.mocked(useSupabaseClient).mockReturnValue({
auth: { onAuthStateChange: vi.fn() },
rpc: vi.fn().mockResolvedValue({ data: null, error: new Error("fail") }),
} as any)
// rest of test
})The as any cast is usually necessary since the full SupabaseClient type has many methods you are not mocking. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
I'm hoping someone has worked through a similar issue, but I'm having the hardest time figuring out how to mock the
useSupabaseClientcomposable. Granted I'm not great at Vitest. Here is what I have currently which has gotten past the first couple sets of Supabase/vitest-related errors:In my Vue component, I have a fairly simple use of an .rpc function:
const fetchDashboard = async () => { const supabase = useSupabaseClient<Database>(); console.log(`supbase: `, supabase); <-- Returns undefined when running tests loading.value = true; try { const user = useSupabaseUser(); // fetch dashboard data from supabase const { data: pageData, error } = await supabase .rpc('get_dashboard_data', { p_user_id: user.value!.id, }) .returns<DashboardData>(); ... } catch (err) { console.log(`fetchDashboard err: `, err); console.error({ err }); } finally { loading.value = false; } }; await fetchDashboard();And here is the error I'm seeing when running the test from my terminal:
So how do I correctly mock the .rpc function on the useSupabaseClient composable? For that matter, is there a better way of handling this in general?
Edit
I should also mention that I've been receiving env variable errors when running the vitest tests, even though they are most definitely set in my .env file and works just fine in the application.
All reactions