如何mock/stub vue-i18 n?

ldxq2e6h  于 2023-05-29  发布在  Vue.js
关注(0)|答案(6)|浏览(427)

我已经开始用Vitest替换Jest,用于我的Vue 3应用程序中的单元测试库。
我试图为一个使用vue-i18n库来翻译其中文本的组件编写单元测试,但当我试图在测试文件中挂载此组件时,它失败并出现错误:
参考错误:t未定义
使用vitest库编写测试时,从import { useI18n } from 'vue-i18n'中存根/模拟t的正确方法是什么?
请注意,从Vue 2升级到Vue 3并不起作用:

const wrapper = shallowMount(MyComponent, {
  global: {
    mocks: {
      $t: () => {}
    }
  }
})

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

"vue": "^3.2.31",
"vue-i18n": "^9.2.0-beta.14",
"vite": "^2.9.0",
"vitest": "^0.10.2"

谢谢!

mbzjlibv

mbzjlibv1#

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

// 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',
        }
    })
);
// tests/unit.setup.ts
import { config } from "@vue/test-utils"

config.global.mocks = {
  $t: tKey => tKey; // just return translation key
};
inn6fuwd

inn6fuwd2#

import { createI18n } from 'vue-i18n';

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

ogsagwnx3#

Panos Vakalopoulos的回答对我很有效。
代码可以在全球运行。
参见https://test-utils.vuejs.org/migration/#no-more-createlocalvue

// vite.config.ts
export default defineConfig(
    // add config for test
    test: {
        environment: 'jsdom',
        setupFiles: 'vitest.setup.ts',
    }
);

// vitest.setup.ts'
import { config } from '@vue/test-utils'
import { createI18n } from 'vue-i18n'
const i18n = createI18n()
config.global.plugins = [i18n]
// YourComponent.vue
<div id="app">
    <p>{{ t("message.hello") }}</p>
</div>

<script lang="ts" setup>
    import { useI18n } from 'vue-i18n'
    const { t } = useI18n()
</script>
// component_test.ts
describe('xxx', () => {
    it('yyy', () => {
        const wrapper = mount(YourComponent);
    }
})

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

// YourComponent.vue
<div id="app">
    <p>{{ $t("message.hello") }}</p>
</div>
// tests/unit.setup.ts
import { config } from "@vue/test-utils"

config.global.mocks = {
    $t: tKey => tKey; // just return translation key
};
oyxsuwqo

oyxsuwqo4#

我读了this tutorial,它教我模仿 vue-router,然后我为 * vue-i18 n * 做了一个类似的解决方案,它工作了。
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>

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");
  });
});

你可以看到,它适用于t$t
这不是理想的方式。总有一天,我会努力弄清楚如何在全球范围内进行每项测试。

nxagd54h

nxagd54h5#

成分API的全球解决方案:

import { vi } from 'vitest';

vi.mock('vue-i18n', () => ({
  useI18n: () => ({
    t: (key: string) => key,
    d: (key: string) => key,
  }),
}));
mpgws1up

mpgws1up6#

如果您使用的是composition API,而获取$setup.t不是一个函数,这是因为您可能在测试设置中错误地配置了createI18n示例:

import { config } from '@vue/test-utils'
import { createI18n } from 'vue-i18n'

const i18n = createI18n({
  legacy: false,
  allowComposition: true
})
config.global.plugins = [i18n]

请注意,您需要添加legacy: falseallowComposition: true才能使用composition API,否则$setup.t将不会被定义,您将得到$setup.t不是函数错误。

相关问题