Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot read property '_t' of undefined. Vue-i18t injection with @vue/test-utils mount() #754

Closed
alexey2baranov opened this issue Dec 22, 2019 · 4 comments

Comments

@alexey2baranov
Copy link

vue & vue-i18n version

2.6.10, 8.15.1

Reproduction Link

Unfortunately I don't know how to reproduce unit testing with jsfiddle. It would be very helpfull if you provide base template for unit testing like you did http://jsfiddle.net/r8qnsfb1/

Steps to reproduce

jest test.spec.js

What is Expected?

test success

What is actually happening?

TypeError: Cannot read property '_t' of undefined

Description

hello!
I got this error inside unit test. I found very similar Issue in #276 except we don't use Vue.extends() and $mount() syntax in our code and tests. We try inject vue-i18n using regular @vue/test-utils mount() function and get this error.

// test.spec.js
import Vue from "vue";

import VueI18n from 'vue-i18n'
Vue.use(VueI18n)
const vueI18n= new VueI18n()
import {mount} from '@vue/test-utils'

import Demo from '../../../src/components/Demo'

it('vue-i18n test', async () => {
    const wrapper = mount(Demo, {  // try to inject vue-i18n
        vueI18n,
    })    // mount({ vueI18n,   ...Demo}) not works too

})

As you can see we use mount(component, options) . And get error

TypeError: Cannot read property '_t' of undefined



  at Proxy.Vue.$t (node_modules/vue-i18n/dist/vue-i18n.common.js:179:17)
  at Proxy.render (src/components/Demo.vue:17:154)
  at VueComponent.Vue._render (node_modules/vue/dist/vue.runtime.common.dev.js:3532:22)
  at VueComponent.updateComponent (node_modules/vue/dist/vue.runtime.common.dev.js:4048:21)
  at Watcher.get (node_modules/vue/dist/vue.runtime.common.dev.js:4459:25)
  at new Watcher (node_modules/vue/dist/vue.runtime.common.dev.js:4448:12)
  at mountComponent (node_modules/vue/dist/vue.runtime.common.dev.js:4055:3)
  at VueComponent.Object.<anonymous>.Vue.$mount (node_modules/vue/dist/vue.runtime.common.dev.js:8386:10)
  at init (node_modules/vue/dist/vue.runtime.common.dev.js:3112:13)
  at createComponent (node_modules/vue/dist/vue.runtime.common.dev.js:5952:9)
  at createElm (node_modules/vue/dist/vue.runtime.common.dev.js:5899:9)
  at VueComponent.patch [as __patch__] (node_modules/vue/dist/vue.runtime.common.dev.js:6449:7)
  at VueComponent.Vue._update (node_modules/vue/dist/vue.runtime.common.dev.js:3927:19)
  at VueComponent.updateComponent (node_modules/vue/dist/vue.runtime.common.dev.js:4048:10)
  at Watcher.get (node_modules/vue/dist/vue.runtime.common.dev.js:4459:25)
  at new Watcher (node_modules/vue/dist/vue.runtime.common.dev.js:4448:12)
  at mountComponent (node_modules/vue/dist/vue.runtime.common.dev.js:4055:3)
  at VueComponent.Object.<anonymous>.Vue.$mount (node_modules/vue/dist/vue.runtime.common.dev.js:8386:10)
  at mount (node_modules/@vue/test-utils/dist/vue-test-utils.js:8649:21)
  at Object.<anonymous> (tests/unit/components/VueI18n.spec.js:11:21)
<template>
    <div>
        {{ $t('profile.lastName') }}
    </div>
</template>
<script>
    export default {

    }
</script>
@jamisuomalainen
Copy link

jamisuomalainen commented Jan 10, 2020

Hi there! Try using the correct key name just as you would when adding vue-i18n to your app:

   import Vue from "vue";

   import VueI18n from 'vue-i18n'
   Vue.use(VueI18n)
-  const vueI18n= new VueI18n()
+  const i18n = new VueI18n()
   import {mount} from '@vue/test-utils'

   import Demo from '../../../src/components/Demo'

   it('vue-i18n test', async () => {
       const wrapper = mount(Demo, {  // try to inject vue-i18n
-          vueI18n,
+          i18n,
       })    // mount({ vueI18n,   ...Demo}) not works too

   })

That should do the trick.

@alexey2baranov
Copy link
Author

Thanks

@jbnv
Copy link

jbnv commented Jan 27, 2020

I'm getting this error in a pure-JS single-file-component with code akin to that below. After getting the error with $t = this.$i18n.t, I tried importing i18n directly. Still got the error.

Component that is throwing the error:

export default {
  render(vnode) {
    const $t = this.$i18n.t; // or require(...).i18n.t
    return vnode(
      require('another/component'), 
      {
        props: {
          columns: [
            { key: 'name', label: $t('fields.name') }, 
            { 
              key: 'role', label: $t('fields.role.title'),
              formatter: (value, key, item) => $t("fields.role.values." + value)
            }, 
            { key: 'actions', label: $t('Actions') }
          ]
        },
      }
    );
  }
}

My base i18n configuration:

import VueI18n from 'vue-i18n';
Vue.use(VueI18n);
const i18n = new VueI18n({
	locale: require('./util/language').default,
	fallbackLocale: 'en',
	messages: {
		"en": require('./i18n/en.json'),
	},
	silentTranslationWarn: true
});

@jbnv
Copy link

jbnv commented Jan 27, 2020

Looks like my resolution is to change const $t = this.$i18n.t; to const $t = this.$i18n.t.bind(this.$i18n);.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants