Search code examples
typescriptvue.jsunit-testingjestjsvue-i18n

Error in render: "TypeError: Cannot read property '_t' of undefined" in Unit Test with Jest


I wrote a unit test for my Vue.js component but after hours of trying and searching the internet, I still keep getting this error:

console.error node_modules/vue/dist/vue.runtime.common.dev.js:1884
TypeError: Cannot read property '_t' of undefined
at Proxy.Vue.$t ([...]\node_modules\vue-i18n\dist\vue-i18n.common.js:194:17)
at Proxy.render ([...]\src\components\Foo.vue:186:175)
at [...]

In my Foo.vue component I use $t like this, which is provided by the vue-i18n plugin:

<template>
  <b-form-group :label="$t('foo.label')">
    [...]
  </b-form-group>
</template>

My Foo.spec.ts looks like this:

import { createLocalVue, shallowMount, mount } from "@vue/test-utils";
import Foo from "@/components/Foo.vue";
import { i18n } from "@/i18n";

describe("Foo", () => {
  const localVue = createLocalVue() as any;
  localVue.use(i18n);
  
  const wrapper = mount(Foo, { localVue } ) as any;

  describe("removeLabel", () => {  
    it("should remove label", async () => {
      // Arrange
      const index = 1;

      // Act
      wrapper.vm.removeLabel(index);

      // Assert
      expect(wrapper.isVueInstance()).toBeTruthy();
      // [more expectations... ]
    });
  });
});

I checked all other Stack Overflow issue with the same error message, but in none the unit test causes this error.
As per Vue.js docs, I tried to hand a mock into the mount function for _t, but with no success:

const $mocks = { $t: () => {} };
const wrapper = mount(Foo, { localVue, mocks: { $mocks } }) as any;

Any hint will be appreciated.


Solution

  • Going through Github issues discussing that very error, I found this magic comment by cesalberca:

    "This works as long as it's shallow. If you mount the component and any subcomponent uses translations the tests will fail [...]"

    I replaced mount by shallowMount and now the error is gone:

    // const wrapper = mount(Foo, { localVue, mocks: { $t: () => {} } }) as any;
    
    const wrapper = shallowMount(Foo, { localVue, mocks: { $t: () => {} } }) as any;