如何模拟/存根 vue-i18n?

Mac*_*Ill 13 javascript vue.js vue-i18n vuejs3 vitest

我已经开始将Vue 3 应用程序中的单元测试库的Jest 替换为Vitest 。

我正在尝试为使用vue-i18n库翻译其中文本的组件编写单元测试,但是当我尝试在测试文件中安装此组件时,它失败并出现错误:

参考错误:t 未定义

使用 vitest 库编写测试时t进行存根/模拟的正确方法是什么?import { useI18n } from 'vue-i18n'

请注意,自从从 Vue2 升级到 Vue3 后,这不起作用:

const wrapper = shallowMount(MyComponent, {
  global: {
    mocks: {
      $t: () => {}
    }
  }
})
Run Code Online (Sandbox Code Playgroud)

以下是一些值得注意的软件包版本的列表:

"vue": "^3.2.31",
"vue-i18n": "^9.2.0-beta.14",
"vite": "^2.9.0",
"vitest": "^0.10.2"
Run Code Online (Sandbox Code Playgroud)

谢谢!

Luc*_*oke 8

我想你想在全球范围内模拟这个,不需要在每个测试套件中放置相同的代码。

// vitest.config.ts
import { mergeConfig } from 'vite';
import { defineConfig } from 'vitest/config';
import viteConfig from './vite.config';

export default defineConfig(
    mergeConfig(viteConfig, { // extending app vite config
        test: {
            setupFiles: ['tests/unit.setup.ts'],
            environment: 'jsdom',
        }
    })
);
Run Code Online (Sandbox Code Playgroud)
// tests/unit.setup.ts
import { config } from "@vue/test-utils"

config.global.mocks = {
  $t: tKey => tKey; // just return translation key
};
Run Code Online (Sandbox Code Playgroud)

  • 仍然收到“TypeError: $setup.t is not a function” (2认同)
  • 在我的设置脚本中,我执行 `import { useI18n } from 'vue-i18n'; const { t } = useI18n();`。 (2认同)

Zho*_*ang 5

Panos Vakalopoulos\xe2\x80\x99s 的答案对我有用。

\n

而且代码可以在全球范围内运行。

\n

请参阅https://test-utils.vuejs.org/migration/#no-more-createlocalvue

\n
// vite.config.ts\nexport default defineConfig(\n    // add config for test\n    test: {\n        environment: \'jsdom\',\n        setupFiles: \'vitest.setup.ts\',\n    }\n);\n\n// vitest.setup.ts\'\nimport { config } from \'@vue/test-utils\'\nimport { createI18n } from \'vue-i18n\'\nconst i18n = createI18n()\nconfig.global.plugins = [i18n]\n
Run Code Online (Sandbox Code Playgroud)\n
// YourComponent.vue\n<div id="app">\n    <p>{{ t("message.hello") }}</p>\n</div>\n\n<script lang="ts" setup>\n    import { useI18n } from \'vue-i18n\'\n    const { t } = useI18n()\n</script>\n
Run Code Online (Sandbox Code Playgroud)\n
// component_test.ts\ndescribe(\'xxx\', () => {\n    it(\'yyy\', () => {\n        const wrapper = mount(YourComponent);\n    }\n})\n
Run Code Online (Sandbox Code Playgroud)\n

请注意,如果您使用全局配置$t,Luckylooke 的答案将会起作用。

\n
// YourComponent.vue\n<div id="app">\n    <p>{{ $t("message.hello") }}</p>\n</div>\n
Run Code Online (Sandbox Code Playgroud)\n
// tests/unit.setup.ts\nimport { config } from "@vue/test-utils"\n\nconfig.global.mocks = {\n    $t: tKey => tKey; // just return translation key\n};\n
Run Code Online (Sandbox Code Playgroud)\n

  • 在您的应用程序上使用组合 API 时怎么样?我按照您的步骤操作,但收到“TypeError: $setup.t is not a function”错误。 (2认同)

小智 5

我读了这个教程,教如何模拟vue-router,然后我为vue-i18n做了一个类似的解决方案并且它有效。

Component (HelloWorld.vue)

<script setup>
import { useI18n } from "vue-i18n";

const { t } = useI18n();
</script>

<template>
  <div class="greetings">
    <h1>{{ t("commonsmessagehello") }}</h1>
    <h2>{{ t("localhello") }}</h2>
    <h2>{{ $t("message.success") }}</h2>
  </div>
</template>

<i18n src="../commons/locales.json"></i18n>
<i18n>
{
  "enUS": {
    "localhello": "local helloooooo"
  }
}
</i18n>
Run Code Online (Sandbox Code Playgroud)

Test

import { describe, it, expect, vi } from "vitest";
import { mount, config } from "@vue/test-utils";
import { useI18n } from "vue-i18n";
import HelloWorld from "../HelloWorld.vue";

vi.mock("vue-i18n");

useI18n.mockReturnValue({
  t: (tKey) => tKey,
});

config.global.mocks = {
  $t: (tKey) => tKey,
};

describe("HelloWorld", () => {
  it("renders properly", () => {
    const wrapper = mount(HelloWorld, { });
    expect(wrapper.text()).toContain("message.success");
  });
});
Run Code Online (Sandbox Code Playgroud)

如您所见,它适用于t$t

这不是理想的方式。有一天我会尝试找出如何在全球范围内为每个测试进行此操作。


Pan*_*los 4

import { createI18n } from 'vue-i18n';

describe('xxx', () => {
   it('yyy', () => {
      const i18n = createI18n({
         messages: {
            gb: {},
            nl: {},
            ...
         }
      });
      
      const wrapper = mount(YourComponent, {
         global: {
            plugins: [i18n]
         }
      });
   }
})
Run Code Online (Sandbox Code Playgroud)