ve3测试库- vue-i18n未加载文本



我似乎不能让下面的例子与ve3和测试库一起工作。测试https://github.com/testing-library/vue-testing-library/blob/main/src//translations-vue-i18n.js

我甚至尝试这样修改示例,以便通过向mock中注入消息来识别$t,但没有成功。

有没有人有一个例子,与vue 3工作?

详情如下…

Translations.spec.js

import '@testing-library/jest-dom'
import {render, fireEvent} from '@testing-library/vue'
import Vuei18n from 'vue-i18n'
import Translations from '@/components/Translations'
const messages = {
en: {
Hello: 'Hello!',
message: {
hello: 'Hello!'
}
},
ja: {
Hello: 'こんにちは',
message: {
hello: 'こんにちは'
}
},
}
test('renders translations', async () => {
const {queryByText, getByText} = render(Translations, {
global: {
mocks: {
$t: (messages) => messages
}
}
}, vue => {
// Let's register and configure Vuei18n normally
vue.use(Vuei18n)
const i18n = new Vuei18n({
locale: 'ja',
fallbackLocale: 'ja',
messages,
})
// Notice how we return an object from the callback function. It will be
// merged as an additional option on the created Vue instance.
return {
i18n,
}
})
//expect(getByText('Hello!')).toBeInTheDocument()
//await fireEvent.click(getByText('Japanese'))
expect(getByText('こんにちは')).toBeInTheDocument()
//expect(queryByText('Hello!')).not.toBeInTheDocument()
})

Translations.vue

<template>
<div>
<h2>{{ $t("Hello") }}</h2>
<h2>{{ $t("message.hello") }}</h2>
<button @click="switchLocale('en')">English</button>
<button @click="switchLocale('ja')">Japanese</button>
</div>
</template>
<script>
export default {
name: 'Translations',
methods: {
switchLocale(locale) {
this.$i18n.locale = locale
},
},
}
</script>

package.json

{
"name": "mc",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"test:unit": "vue-cli-service test:unit"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.35",
"@fortawesome/free-solid-svg-icons": "^5.15.3",
"@fortawesome/vue-fontawesome": "^3.0.0-4",
"@popperjs/core": "^2.9.2",
"bootstrap": "^5.0.2",
"core-js": "^3.6.5",
"es6-promise": "^4.2.8",
"vue": "^3.1.4",
"vue-hotjar": "^1.4.0",
"vue-i18n": "^9.1.6",
"vue-loader": "^16.2.0",
"vue-router": "^4.0.10",
"vuex": "^4.0.2"
},
"devDependencies": {
"@babel/core": "^7.14.8",
"@babel/preset-env": "^7.14.8",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/vue": "^6.4.2",
"@vue/cli-plugin-babel": "^4.5.13",
"@vue/cli-plugin-eslint": "^4.5.13",
"@vue/cli-plugin-router": "^4.5.13",
"@vue/cli-plugin-unit-jest": "^4.5.13",
"@vue/cli-plugin-vuex": "^4.5.13",
"@vue/cli-service": "^4.5.13",
"@vue/compiler-sfc": "^3.1.4",
"@vue/eslint-config-prettier": "^6.0.0",
"@vue/test-utils": "^2.0.0-rc.9",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.4.0",
"eslint-plugin-vue": "^7.0.0",
"flush-promises": "^1.0.2",
"prettier": "^2.3.2",
"typescript": "^4.3.5",
"vue-jest": "^5.0.0-alpha.10"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/vue3-essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}

误差

FAIL  tests/unit/Translations.spec.js        
● renders translations
TestingLibraryElementError: Unable to find an element with the text: こんにちは. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.
<body>
<div>
<div>
<h2>
Hello
</h2>
<h2>
message.hello
</h2>
<button>
English
</button>
<button>
Japanese
</button>
</div>
</div>
</body>
47 |   //await fireEvent.click(getByText('Japanese'))
48 |
> 49 |   expect(getByText('こんにちは')).toBeInTheDocument()
|          ^
50 |
51 |   //expect(queryByText('Hello!')).not.toBeInTheDocument()
52 | })

我有同样的问题,并解决它像这样:

我正在使用下一个版本的@vue/test-utils和vue-jest ("@vue/test-utils"; "^2.0.0-rc.16"+"vue-jest"^ 5.0.0-alpha.10")。

我创建了一个名为jest.init.js的文件(你可以随意命名)

import { config } from '@vue/test-utils';
import translations from '@/locales/en';

config.global.mocks = {
$t: (msg) => translations[msg],
};

,然后将其初始化为jest.config.js

中的安装文件
module.exports = {
...
setupFiles: [
'./tests/unit/jest.init.js',
],
...
};

这个答案是为每个在使用没有全局$t来模拟的Composition API时遇到这个问题的人准备的。

我通过在src/plugins/i18n.ts中导出createConfiguredI18n函数来解决它:

import { createI18n, I18nOptions } from 'vue-i18n'
import deDE from '@/locales/de-DE.json'
import enUS from '@/locales/en-US.json'
// Type-define 'de-DE' as the master schema for the resource
type MessageSchema = typeof deDE
export function createConfiguredI18n(locale: string, fallbackLocale: string) {
return createI18n<I18nOptions, [MessageSchema], 'de-DE' | 'en-US'>({
locale: locale || 'en-US',
fallbackLocale: fallbackLocale || 'en-US',
messages: {
'de-DE': deDE,
'en-US': enUS,
},
})
}
export const i18n = createConfiguredI18n('de-DE', 'en-US')

然后在单元测试中,您可以使用翻译来初始化vue-i18n:

import {flushPromises, mount, VueWrapper} from '@vue/test-utils'
import {nextTick} from 'vue'
import {createConfiguredI18n} from '@/plugins/i18n'
...
describe('SubjectUnderTest', () => {
it('should display translation "FooBar"', async () => {
const locale = 'de-DE'
const fallbackLocale = 'en-US'
const wrapper = await createWrapper({locale, fallbackLocale})
...
}
async function createWrapper(options: {
locale: string
fallbackLocale: string
}): Promise<VueWrapper> {
const i18n = createConfiguredI18n(options.locale, options.fallbackLocale)
const wrapper = mount(sut, {
global: {
plugins: [i18n],
},
})
await nextTick()
await flushPromises()
return wrapper
}
}

如果您不想要翻译,而是模拟它们并只检查键,您可以在单元测试中执行以下操作:

import {flushPromises, mount, VueWrapper} from '@vue/test-utils'
import {nextTick} from 'vue'
import {i18n} from '@/plugins/i18n'
...
i18n.global.t = (key) => key
describe('SubjectUnderTest', () => {
it('should display translation for key "foo.bar"', async () => {
const wrapper = await createWrapper()
...
}
async function createWrapper(): Promise<VueWrapper> {
const wrapper = mount(sut, {
global: {
plugins: [i18n],
},
})
await nextTick()
await flushPromises()
return wrapper
}
}

最新更新