You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Vitest中模拟__()国际化函数?

如何模拟国际化函数__()以解决Vitest测试报错问题?

问题描述

使用Laravel+Vue+Inertiajs技术栈,在通过Vitest测试组件时出现报错:
TypeError: _ctx.__ is not a function

已通过Lingua库将Laravel语言文件转换为JS,使__()翻译函数在全局可用(已在app.js中引入),当前不需要测试该函数的翻译准确性,想确认模拟__()是否为正确解决方案。

示例组件代码

<script setup>
import Checkbox from '@/Components/Checkbox.vue';
import InputError from '@/Components/InputError.vue';
import InputLabel from '@/Components/InputLabel.vue';
import PrimaryButton from '@/Components/PrimaryButton.vue';
import { useForm, usePage } from '@inertiajs/vue3';


const user = usePage().props.auth.user;

const form = useForm({
    inboxable: user.inboxable ?? true,
});

const saveForm = (() => {
    form.patch(route('privacy.update'), {
        preserveScroll: true,
    });
});

</script>

<template>
    <section>
        <header>
            <h2 class="text-lg font-medium text-gray-900">{{__('user.privacyTitle')}}</h2>

            <p class="mt-1 text-sm text-gray-600">
                {{__('user.privacyDescription')}}
            </p>
        </header>

        <div></div>

        <form @submit.prevent="saveForm" class="mt-6 space-y-6">
            <div>
                <InputLabel for="inboxable" :value="__('user.privacyInboxable')" />
                <Checkbox id="inboxable" v-model="form.inboxable" :checked="form.inboxable" />
                <InputError class="mt-2" :message="form.errors.inboxable" />
            </div>

            <div class="flex items-center gap-4">
                <PrimaryButton :disabled="form.processing">{{__('user.privacySave')}}</PrimaryButton>

                <Transition enter-from-class="opacity-0" leave-to-class="opacity-0" class="__ition ease-in-out">
                    <p v-if="form.recentlySuccessful" class="text-sm text-gray-600">{{__('user.profileConfirmed')}}</p>
                </Transition>
            </div>
        </form>
    </section>
</template>

vite.config配置

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';
import path from 'path';
import { run } from 'vite-plugin-run'
import basicSsl from '@vitejs/plugin-basic-ssl'

export default defineConfig({
    esbuild: {
        jsxFactory: 'h',
        jsxFragment: 'Fragment'
      },
    plugins: [
        basicSsl(),
        laravel({
            input: 'resources/js/app.js',
            refresh: true,
        }),
        vue({
            template: {
                transformAssetUrls: {
                    base: null,
                    includeAbsolute: false,
                },
            },
        }),
        run({
            name: "generate translations",
            run: ['php', 'artisan', 'lingua:generate'],
            pattern: ['resources/lang/**', 'lang/**'],
        }),
    ],
    server: {
        hmr: {
          host: "192.168.10.1",
          https: true,
        },
        host: "0.0.0.0",
        https: true,
    },
    resolve: {
        alias: {
            'lingua-js': path.resolve(__dirname, 'vendor/cyberwolfstudio/lingua/dist/index.js')
        },
    },
    test: {
        globals: true,
        environment: "jsdom",
      },
});

解决方案

模拟__()函数是完全可行的方案,以下是三种实现方式:

  • 单个测试文件内全局模拟
    在测试文件顶部添加全局函数模拟:
import { vi } from 'vitest';

// 直接返回传入的翻译键,满足测试组件渲染需求
vi.stubGlobal('__', (key) => key);
  • 全局测试前置配置
    修改vite.config.js的test字段,指定前置配置文件:
test: {
    globals: true,
    environment: "jsdom",
    setupFiles: ['./tests/setup.js'],
},

创建tests/setup.js文件并写入:

import { vi } from 'vitest';

vi.stubGlobal('__', (key) => key);
  • 组件挂载时注入
    在挂载组件时通过全局配置注入函数:
import { mount } from '@vue/test-utils';
import PrivacyComponent from './PrivacyComponent.vue';

test('组件渲染正常', () => {
    const wrapper = mount(PrivacyComponent, {
        global: {
            config: {
                globalProperties: {
                    __: (key) => key,
                },
            },
        },
    });
    // 编写断言逻辑
});

以上方式均可解决测试时__()函数未定义的报错,可根据测试结构选择合适的方案。

内容的提问来源于stack exchange,提问作者Ben

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 08:27:02