KingGary
KingGary

Reputation: 638

Vuetify Jest Unknown custom element <v-*>

I am writing unit tests for my project, using Jest. Project is based on Vue, Vuetify (1.5) and TypeScript (and vue-property-decorator).

I have basic wrapper for <v-btn>. It looks like this:

<template>
  <v-btn
    :round="!square"
    v-on="$listeners"
  >
    <slot />
  </v-btn>
</template>

<script lang="ts">
import { Vue, Prop, Component } from 'vue-property-decorator';

import { VBtn } from 'vuetify/lib';

@Component({
  components: {
    VBtn,
  },
})
export default class Btn extends Vue {
  @Prop({ default: false, type: Boolean }) private square!: boolean;
}
</script>

And I wrote basic test, just to mount this component:

import { mount } from '@vue/test-utils'
import Vue from 'vue';
import Btn from './Btn.vue';

describe('Btn', () => {

  it('should render button', () => {
    const wrapper = mount(Btn, {
      propsData: {
        onClick: () => {}
      }
    });

    console.log((Vue as any).options.components.VBtn)

    console.log('=======================');
    console.log(wrapper.html());
    console.log('=======================');
  });
});

When running test I'm getting this error:

  console.error node_modules/vue/dist/vue.runtime.common.dev.js:621
    [Vue warn]: Unknown custom element: <v-btn> - did you register the component correctly? For recursive components, make sure to provide the "name" option.

    found in

    ---> <Btn>

But I know that component is registered - it works when running the project (not test). Also, I have console log in test that checks if it is registered (console.log((Vue as any).options.components.VBtn)) and it shows that component is registered globally.

Here is my jest.config.js:

module.exports = {
  moduleFileExtensions: [
    "js",
    "ts",
    "json",
    "vue"
  ],
  moduleNameMapper: {
    "^@/(.*)$": "<rootDir>/src/$1",
    "^vuetify/lib$": "vuetify",
  },
  modulePaths: [
    "<rootDir>/src",
    "<rootDir>/node_modules"
  ],
  transform: {
    ".+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$": "jest-transform-stub",
    "^.+\\.ts?$": "ts-jest",
    ".*\\.(vue)$": "vue-jest",
  },
  transformIgnorePatterns: [
    "<rootDir>/node_modules/(?!(vuetify)/)",
  ],
  testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.(js?|ts?)$",
  setupFilesAfterEnv: ['<rootDir>/tests/unit/setup.ts'],
}

And setup.ts file:

import Vue from 'vue';
import Vuetify from 'vuetify';

Vue.config.productionTip = false;
Vue.use(Vuetify);

I was trying to move code from setup.ts to the test but it doesn't changed anything. I think there may be problem with 'vue-property-decorator' but my whole project is based on it so I don't want to change it. Can you help me? Maybe something is wrong in my Jest transform configuration?

Upvotes: 17

Views: 8934

Answers (2)

Daniel Danielecki
Daniel Danielecki

Reputation: 10572

Create index.js/index.ts in your tests/unit folder with the setup below

import Vue from "vue";
import Vuetify from "vuetify";
Vue.config.productionTip = false;
Vue.use(Vuetify);

Update your jest.config.js in the root of your project

module.exports = {
  ...
  setupFiles: ["<rootDir>/tests/unit/index.ts"],
};

It looks like a autogenerated bug when generating Vuetify project from the CLI. In short, it's because Vuetify is not registered in your test project.

Upvotes: 26

KingGary
KingGary

Reputation: 638

I managed to solve this problem. Had to change two lines of code:

In my Btn component, changed VBtn import to: import { VBtn } from 'vuetify/lib/components/VBtn'; (imported from vuetify/lib/components/VBtn, not from vuetify/lib).

In jest.config.js update in moduleNameMapper to 'vuetify/lib(.*)': '<rootDir>/node_modules/vuetify/es5$1'.

And that is all, now it works :)

My whole jest.config.js:

module.exports = {
  moduleFileExtensions: [
    "js",
    "ts",
    "json",
    "vue"
  ],
  moduleNameMapper: {
    "^@/(.*)$": "<rootDir>/src/$1",
    'vuetify/lib(.*)': '<rootDir>/node_modules/vuetify/es5$1',
  },
  modulePaths: [
    "<rootDir>/src",
    "<rootDir>/node_modules"
  ],
  transform: {
    ".+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$": "jest-transform-stub",
    "^.+\\.ts?$": "ts-jest",
    ".*\\.(vue)$": "vue-jest",
  },
  transformIgnorePatterns: [
    "<rootDir>/node_modules/(?!(vuetify)/)",
  ],
  testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.(js?|ts?)$",
  setupFilesAfterEnv: ['<rootDir>/tests/unit/setup.ts'],
}

Upvotes: 8

Related Questions