How to check if navigateTo was called in nuxt.js
Asked Answered
F

3

7

I'm working on a Nuxt.js project and using Vitest for unit testing. I need to verify if the navigateTo function from Nuxt.js is called with a specific path in my tests.

Here's the relevant part of my component (Form.vue), where navigateTo is invoked:

// Form.vue

const onClick = () => {
    await navigateTo('/')
}
// Form.test.ts

const navigateToMock = vi.fn()

it('When submit clicked, Then make redirect', async () => {
  const wrapper = mount(...)

  await wrapper.find("[data-testid='login']").trigger('submit')
  await flushPromises()

  expect(navigateToMock).toHaveBeenCalledWith('/')
})

I'm struggling to figure out how to spy on or effectively test whether navigateTo was called or not. Does anyone have any suggestions or ideas on how to approach this?

Formulism answered 16/1 at 15:56 Comment(0)
R
0

you can mock the navigateTo module like this in your vitest.setup:

export const navigateToMock = vi.fn();

const mockModules = () => {
 vi.doMock('#app', () => ({
  navigateTo: navigateToMock,
 }));

and then check in your test file like this:

 expect(navigateToMock).toHaveBeenCalledWith('/expectedPath');

further information about vitest mocking modules

Raconteur answered 3/7 at 14:43 Comment(6)
This does not work for me, I get Error: Failed to resolve import "#app" from "components/MyComponent.vue". Does the file exist?Arillode
you need to configure it as an alias in your vitest.config.ts file like this: resolve: { alias: { '#app': path.resolve(__dirname, './node_modules/nuxt/dist/app/index.d.ts'), },},Raconteur
defining aliases is also described here: https://mcmap.net/q/351101/-vitest-src-folder-alias-not-resolved-in-test-filesRaconteur
I tried this and then had to explicitly import it in MyComponent.vue (import { navigateTo } from "#app"). If I now run my test, I get ReferenceError: __NUXT_ASYNC_CONTEXT__ is not defined. I haven't really had luck getting Vitest working with Nuxt..Arillode
Do you run your test in a async context? I guess without seeing your code, I might not be able to help. Did you consider to open a separate question?Raconteur
I've found a different solution that works for me, see my answer https://mcmap.net/q/1570975/-how-to-check-if-navigateto-was-called-in-nuxt-jsArillode
C
0

navigateTo can be mocked using mockNuxtImport from @nuxt/test-utils/runtime:

import { mockNuxtImport } from '@nuxt/test-utils/runtime';

mockNuxtImport('navigateTo', () => vi.fn());

Note: if you don't have @nuxt/test-utils in your project yet, we had to change some package versions to make it work:

  • vitest: ^0.30.1 => ^1.5.0
  • vitest-environment-nuxt: ^0.10.1 => ^1.0.0
  • nuxt-vitest: removed
  • @nuxt/test-utils: added as ^3.9.0, currently using ^3.14.0
Capers answered 7/8 at 23:18 Comment(0)
A
0

I've made it work by using vi.stubGlobal like this:

it('navigateTo', async () => {
  const navigateToMock = vi.fn();
  vi.stubGlobal("navigateTo", navigateToMock);

  const wrapper = mount(MyComponent);

  // ...

  expect(navigateToMock).toHaveBeenCalledWith('/');
})
Arillode answered 24/8 at 9:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.