如何使用 vitest 模拟可组合项?

问题描述 投票:0回答:1

我正在简单的 Nuxt.js 项目中学习 TDD。该项目是 Laravel API 的前端。这个项目所做的就是实现所有 Laravel Fortify 选项。所以我使用名为 nuxt-auth-sanctum 的外部包。因为 Fortify,使用 Sanctum。

我的目标是测试这个中间件,它检查用户电子邮件是否已验证:

import { defineNuxtRouteMiddleware, navigateTo } from 'nuxt/app'
import type { User } from '~/models/user'
import { useSanctumAuth } from '#imports' // This is here because VS Code has problem recognising Nuxt.js auto-imports

export default defineNuxtRouteMiddleware(async (to, from) => {
  const { user } = useSanctumAuth<User>()

  // List of routes to exclude from this middleware
  const excludedRoutes = [
    '/auth/login',
  ]

  // Check if the current route is in the excluded routes
  if (excludedRoutes.includes(to.path)) {
    return
  }

  // Check if the user's email is verified
  if (user.value && !user.value.email_verified_at) {
    return navigateTo('/auth/verify-email')
  }
})

这里, useSanctumAuth 是可组合的,来自 nuxt-auth-sanctum 包。它的作用是返回用户。

我想在测试中模拟该可组合项:

import { describe, it, expect, vi, beforeEach } from 'vitest'
import checkEmailVerified from '@/middleware/check-email-verified.global'
import type { RouteLocationNormalized } from 'vue-router'
import { navigateTo } from 'nuxt/app'

vi.mock('nuxt/app', () => ({
  navigateTo: vi.fn(),
  defineNuxtRouteMiddleware: vi.fn((middleware) => middleware),
}))

vi.mock('#imports', async () => ({
  useSanctumAuth: vi.fn(() => ({
    user: {
      value: {
        email_verified_at: null,
      },
    },
  })),
}))

describe('checkEmailVerified middleware', () => {
    beforeEach(() => {
        vi.clearAllMocks()
    })

    it('should allow access to excluded routes without redirection', async () => {
        const to: RouteLocationNormalized = {
          path: '/auth/login',
        } as RouteLocationNormalized

        const from: RouteLocationNormalized = {
          path: '/',
        } as RouteLocationNormalized

        await checkEmailVerified(to, from) // Error: [vitest] No "useNuxtApp" export is defined on the "nuxt/app" mock. Did you forget to return it from "vi.mock"?

        expect(navigateTo).not.toHaveBeenCalled()
   })
})

当我运行测试时,我收到此错误:

[vitest] No "useNuxtApp" export is defined on the "nuxt/app" mock. Did you forget to return it from "vi.mock"?

在那一行:

await checkEmailVerified(to, from)

useNuxtApp 来自 useSanctumAuth 可组合项,我想模拟它。据我所知,模拟可组合(在我的情况下)意味着,真正的代码不会被调用,而是会被模拟。那为什么我会收到这个错误呢?它根本不应该进入 useSanctumAuth 内部。被嘲笑返回用户。

我做错了什么?

vue.js unit-testing nuxt.js tdd vitest
1个回答
0
投票

在@Kapcash 的帮助下,现在可以了。我必须先使用 Nuxt 提供的功能,然后再使用 Vitest。 这是我改变的:而不是

vi.mock('#imports', async () => ({...

现在我有:

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

const mockUser = ref<User | null>(null)
mockNuxtImport('useSanctumAuth', () => {
  return () => ({
    user: mockUser,
  })
})

beforeEach(() => {
        vi.clearAllMocks()
        mockUser.value = null
    })
© www.soinside.com 2019 - 2024. All rights reserved.