我正在简单的 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 内部。被嘲笑返回用户。
我做错了什么?
在@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
})