1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

vitestでNuxtのnavigateToをモックする

Last updated at Posted at 2024-07-18

はじめに

NuxtのnavigateToを以下のような感じでテストしたかったのですが、

utils/sample.ts
export default async () => {
  await navigateTo({
    path: "/",
    query: { redirect: undefined, tenantId: undefined },
  })
}
utils/sample.spec.ts
describe('sample', () => {
  it('navigate to top', async () => {
    const mock = vi.fn() // いい感じにnavigateToをモック
    const expectArgs = {
      path: "/",
      query: { redirect: undefined, tenantId: undefined },
    }

    await sample()
    expect(mock).toHaveBeenCalledWith(expectArgs)
  })
})

そこそこ詰まったので解決方法を記載します。

環境

Nuxt: 3.12.1
vitest: 1.6.0

TL;DR

utils/sample.spec.ts
import * as Nuxt from "#app/composables/router"
import sample from './sample'

describe('sample', () => {
  it('navigate to top', async () => {
    const mock = vi.spyOn(Nuxt, 'navigateTo')
    const expectArgs = {
      path: "/",
      query: { redirect: undefined, tenantId: undefined },
    }

    await sample()
    expect(mock).toHaveBeenCalledWith(expectArgs)
  })
})

内容

まず以下記事を参考に、

以下のようなコードで検証しました。

utils/sample.spec.ts
import * as Nuxt from "nuxt/app"
import sample from './sample'

describe('sample', () => {
  it('navigate to top', async () => {
    const mock = vi.spyOn(Nuxt, 'navigateTo')
    // vi.stubGlobal('navigateTo', mock)
    const expectArgs = {
      path: "/",
      query: { redirect: undefined, tenantId: undefined },
    }
    await sample()
    expect(mock).toHaveBeenCalledWith(expectArgs)
  })
})

しかし、上記コードでテストを実行すると以下エラーとなりました。
(vi.stubGlobalを実行しても変わらず)

エラー
FAIL  utils/sample.spec.ts > sample > navigate to top
AssertionError: expected "navigateTo" to be called with arguments: [ { path: '/', query: { …(2) } } ]

Received: 



Number of calls: 0

 ❯ utils/sample.spec.ts:15:18
     13| 
     14|     await sample()
     15|     expect(mock).toHaveBeenCalledWith(expectArgs)
       |                  ^
     16|   })
     17| })

また、vi.stubGlobalを実行した状態でsample.ts側でglobal.navigateToを実行するとテスト成功しました。

utils/sample.ts
export default async () => {
  await global.navigateTo({
    path: '/',
    query: { redirect: undefined, tenantId: undefined },
  })
}
テスト結果
 ✓ utils/sample.spec.ts (1)
   ✓ sample (1)
     ✓ navigate to top

 Test Files  1 passed (1)
      Tests  1 passed (1)
   Start at  15:39:45
   Duration  221ms

そのため、navigateToは少なくともglobalと違うところで定義されているものを読み込んでいると思われます。

というわけで、.nuxt/imports.d.tsを見てnavigateToがどこからimportされているか確認したところ、以下でした。

.nuxt/imports.d.ts
export { abortNavigation, addRouteMiddleware, defineNuxtRouteMiddleware, setPageLayout, navigateTo, useRoute, useRouter, onBeforeRouteLeave, onBeforeRouteUpdate } from '#app/composables/router';

そのため、モックのためにimportしているモジュールの記載を変更しました。

utils/sample.spec.ts
- import * as Nuxt from "nuxt/app"
+ import * as Nuxt from "#app/composables/router"
import sample from './sample'

describe('sample', () => {
  it('navigate to top', async () => {
    const mock = vi.spyOn(Nuxt, 'navigateTo')
    const expectArgs = {
      path: "/",
      query: { redirect: undefined, tenantId: undefined },
    }

    await sample()
    expect(mock).toHaveBeenCalledWith(expectArgs)
  })
})

これでテスト成功しました。

テスト結果
 ✓ utils/sample.spec.ts (1)
   ✓ sample (1)
     ✓ navigate to top

 Test Files  1 passed (1)
      Tests  1 passed (1)
   Start at  16:13:30
   Duration  163ms
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?