VueJS - 使用vue-test-utils进行单元测试出现错误 - TypeError: _vm.$t不是一个函数。

25

我对Vuejs比较新,并正在测试它的组件。使用vue-test-utils和jest进行测试。得到以下错误 test log

.vue文件包括模板,组件和样式。下面是SignupLayout.vue的一部分,出现了错误 -

<style lang="sass">
@import '../stylesheets/colors'
html[path="/signup"], html[path="/login"]
  height: 100%
  background-image: url("../assets/background.jpg")
  background-size: cover
  background-position: center
  background-repeat: no-repeat
  overflow: hidden

  #signup-layout
    #change-language-button
      .lang-menu
        color: $alto

</style>

测试文件 -

import Vue from 'vue';
import Vuex from 'vuex'
import SignupLayout from '../src/components/SignupLayout.vue';
import { mount, shallow, createLocalVue } from '@vue/test-utils';

const localVue = createLocalVue()

localVue.use(Vuex)

jest.resetModules()

describe('Signup.test.js', () => {
    let cmp
    let actions
    let store
    let getters
    let state

    beforeEach(() => {


        state = {
            email: 'abc@gmail.com'
        }
 
        getters = {
            CURRENT_USER_EMAIL: state => state.email
        }

        store = new Vuex.Store({
            getters
        })


    })

    it('has received ["Login"] as the title property', () => {
        cmp = shallow(SignupLayout, {
            store,
            localVue,
            propsData: {
                title: ['Login']
            },
            data: {
                email: 'abc@dsf.com'
            }
        })
        cmp.update()
        expect(cmp.vm.title).toEqual(['Login'])
    })


})

不明白$t与sass有何关系,希望得到帮助。我已经卡在这里一段时间了。如果需要更多细节,请告诉我。谢谢。

5个回答

26
const $t = () => {}

shallow(Component, {
 mocks:{ $t }
})

这样,您就不需要加载整个i18n库。如果使用Jest,甚至可以使用Sinon或jest.fn()跟踪该函数。


1
+1,它可以工作,谢谢。但是你能否澄清一下你到底在做什么。据我所知,你正在将$t变成箭头函数。 - stanimirsp
4
在测试组件的this上下文中,将$t创建为普通函数的模拟。 - Dobromir Hristov

9
错误不在<style>标签中,因为Jest将编译您的Vue组件并提取JS代码。所以现在可以忽略行错误(我不确定如何修复它)。
但根据您的错误消息,问题似乎与使用vue i18n有关,并且在测试文件中声明Vue组件时缺少它。尝试将以下行添加到测试文件中:
import i18n from 'path-to-your-i18n-file'

// ...

cmp = shallow(SignupLayout, {
  store,
  localVue,
  propsData: {
      title: ['Login']
  },
  data: {
      email: 'abc@dsf.com'
  },
  i18n // <- add the i18n object here
})

4
另一种模拟i18n库的方式是在单独的js文件中对其进行模拟。
import VueTestUtils from '@vue/test-utils';
VueTestUtils.config.mocks.$t = key => key;

并将其添加到Jest配置中

 "setupFiles": ["<rootDir>/setup.js"]

所以,如果您有更多使用资源导入的组件,您就不需要单独模拟它。


1

目前在Vue 3中,你可以尝试以下方法,这对我的情况有所帮助:

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

config.global.mocks.$t = phrase => phrase;

因为
当前配置结构如下: config structure at the moment

0

你也可以全局模拟它,如下所示:

// jest.config.js
{
  // ...
  setupFiles: ['<rootDir>/__tests__/setup.ts'],
}

// __tests__/setup.ts
import Vue, { PluginObject } from 'vue';
import Vuetify from 'vuetify';

const i18nMockPlugin: PluginObject<Vue> = {
  // called by Vue.use(MyPlugin)
  install(Vue) {
    Vue.prototype.$t = function (key: string, _opts: any) {
      return key;
    };
  },
};

Vue.use(Vuetify);
Vue.use(i18nMockPlugin); // mock i18n


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接