I am trying to test a Vue component with Vitest but in order to do that I need to mock auth0
Below is my Navbar.test.ts file, however when I run the test I keep getting the following error Cannot read properties of undefined (reading 'mockReturnValue' as useAuth0 seems to be undefined even though I am imported it at the top of the page. Maybe I'm just not understanding the mocking side of it very well but any help would be appreciated.
import { vi } from 'vitest'
import { ref } from "vue";
import { shallowMount } from '@vue/test-utils'
import { useAuth0 } from '@auth0/auth0-vue';
import NavBar from "@/components/NavBar.vue";
const user = {
email: "user@test.com",
email_verified: true,
sub: ""
};
vi.mock("@auth0/auth0-vue");
const mockedUseAuth0 = vi.mocked(useAuth0, true);
describe("NavBar.vue", () => {
beforeEach(() => {
mockedUseAuth0.mockReturnValue({
isAuthenticated: ref(true),
user: ref(user),
logout: vi.fn(),
loginWithRedirect: vi.fn(),
...
isLoading: ref(false),
});
});
it("mounts", () => {
const wrapper = shallowMount(NavBar, {
props: { },
});
expect(wrapper).toBeTruthy();
});
afterEach(() => vi.clearAllMocks());
});
vi.mocked() is just a helper for TypeScript support. It doesn't mock anything.
The following changes fixes your test:
Don't use a named import of the module in your test. Instead, import the whole module.
Remove vi.mocked(), as this has no effect.
Using the import from step 1, add a useAuth0 property that is set to a mock function, returning a mock of loginWithRedirect.
// NavBar.spec.js
import { describe, it, expect, vi } from 'vitest'
import NavBar from '../NavBar.vue'
import { shallowMount } from '@vue/test-utils'
1️⃣
// import { useAuth0 } from '@auth0/auth0-vue' // DON'T DO THIS
import * as auth0 from '@auth0/auth0-vue'
vi.mock('@auth0/auth0-vue')
2️⃣
// const mockedUseAuth0 = vi.mocked(useAuth0, true)
describe('NavBar', () => {
it('calls useAuth0 > loginWithRedirect', async () => {
const loginWithRedirect = vi.fn()
3️⃣
auth0.useAuth0 = vi.fn().mockImplementation(() => ({
loginWithRedirect,
}))
const wrapper = shallowMount(NavBar)
await wrapper.find('button').trigger('click')
expect(auth0.useAuth0).toHaveBeenCalled()
expect(loginWithRedirect).toHaveBeenCalled()
})
})