The mysterious appearance of the <v-*> custom element in Vuetify Jest

Currently, I am in the process of writing unit tests for my project using Jest. The project itself is built on Vue, Vuetify (1.5), TypeScript, and vue-property-decorator.

One particular area of focus for me has been creating a basic wrapper for the <v-btn> component. Here's how the wrapper code looks:

<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>

To test this component, I have written a simple test case:

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('=======================');
  });
});

However, during the test execution, an error is encountered:

  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>

Despite knowing that the component is registered and works outside of the test environment, the error persists. Furthermore, a console log statement within the test confirms the global registration of the component (

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

I've included snippets from my jest configuration file jest.config.js and the setup.ts file below:

module.exports = {
...
}

// setup.ts
import Vue from 'vue';
import Vuetify from 'vuetify';

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

Attempting to move code from setup.ts into the test scenario did not yield any change in behavior. I suspect there may be an issue related to 'vue-property-decorator', but given that the entire project relies on it, I'm hesitant to make alterations. Could someone lend a hand or offer guidance on rectifying this issue, possibly linked to the Jest transform configuration?

Answer №1

To set up, create a new file named index.js/index.ts within your tests/unit directory with the following code:

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

Next, make sure to update your jest.config.js file located at the root of your project as shown below:

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

This issue likely occurred due to an auto-generated bug when setting up a Vuetify project using the CLI. Essentially, this is because Vuetify was not properly registered in your test project.

Answer №2

After some troubleshooting, I successfully resolved the issue by making two key changes in my code:

Firstly, within my Btn component, I updated the VBtn import to:

import { VBtn } from 'vuetify/lib/components/VBtn';
(making sure it was imported from vuetify/lib/components/VBtn, not just vuetify/lib).

Secondly, in the jest.config.js file, I made an adjustment in the moduleNameMapper section to:

'vuetify/lib(.*)': '<rootDir>/node_modules/vuetify/es5$1'
.

With these modifications, the problem was resolved and everything is now functioning as expected :)

For reference, here is a snippet of my complete 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'],
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips on integrating data from Vuex into your component

How can I effectively utilize the data fetched using the Vuex store's action in a specific component? import axios from 'axios' export default { namespaced: true, state: { items: [] }, actions: { fetchCategories ({state, c ...

What could be causing my "Swiper" component to malfunction in a TypeScript React project?

In my React project, I decided to incorporate the Swiper library. With multiple movie elements that I want to swipe through, I began by importing it as follows: import Swiper from 'react-id-swiper'; Utilizing it in my code like this: <div cla ...

Utilize Vue to save user inputs and dynamically display them in another field

I'm struggling with setting up methods for this. My goal is to have the input data displayed on my table only after clicking the save button. Currently, it's displaying on the table without needing to click save. Can someone assist me with the co ...

Node.js does not allow the extension of the Promise object due to the absence of a base constructor with the required number of type

I'm trying to enhance the Promise object using this code snippet: class MyPromise extends Promise { constructor(executor) { super((resolve, reject) => { return executor(resolve, reject); }); } } But I keep encou ...

Encountered a runtime error while processing 400 requests

Current Situation: When authenticating the username and password in my Ionic 2 project using WebApi 2 token authentication, a token is returned if the credentials are correct. However, a 400 bad request error is returned if the credentials are incorrect. ...

Are you looking to use the 'any' type instead of the 'Object' type? Angular Services can help you with that

I encountered the following error message: Argument of type 'OperatorFunction<APISearch[], APISearch[]>' is not assignable to >parameter of type 'OperatorFunction<Object, APISearch[]>'. The 'Object' type is ...

What are some tips for utilizing the "bottom-row" slot within the "b-table" component in bootstrap-vue?

I am working on a component that utilizes the bootstrap-vue b-table component. My goal is to create a bottom row that displays the sum of each column in the table. However, I encountered an issue where the bottom-row only fills the first column, leaving ...

Using Vue.js to dynamically populate all dropdown menus with a v-for loop

Getting started with vue.js, I have a task where I need to loop through user data and display it in bootstrap cols. The number of cols grows based on the number of registered users. Each col contains user data along with a select element. These select ele ...

Parsing error encountered while trying to handle an unexpected token at line 214, character 33. It appears that an appropriate loader is missing to process this particular file type

I've been developing a Typescript React project for the past few months without any issues. However, things took a turn yesterday when I decided to run npm audit fix and npm audit fix --force in order to address some security concerns that appeared ou ...

Implementing Vuejs v-model with a dynamically named two-dimensional array

How can I create a dynamic v-model with two dynamic variables? Using only one dynamic variable like v-model="shirt_count[brand]" works fine, but when I try v-model="shirt_count[brand][color]", it does not work. See the code snippet belo ...

Using *ngIf with values from an array in *ngFor in Angular 2: How to make it work?

i just started learning angular 2 and ionic, so I'll keep it brief: <ion-card class="acc-page-card" *ngFor="let account of accounts"> <ion-card-content> <!-- Add card content here! --> <ion-item (click)="GoTo('Ac ...

Inspecting a substring of an element dynamically added in VueJs

When I click a button in my form, it adds a new line. The challenge is making sure that each new line evaluates independently and correctly. In this case, the task involves checking the first 2 digits of a barcode against a dataset to determine a match or ...

Preventing the default behavior using event.preventDefault() does not seem to be effective when submitting a

Why is the event.preventDefault() method not functioning properly? <script type="text/javascript" src="vue.js"></script> <div id="app"> <form v-on:submit.prevent="saveData"> <input type="text" name="test"> <button ...

Issue with passing a prop in Vue 3

I'm attempting to send a simple prop to another component in Vue 3.0.11, but for some reason, I can't seem to make it work. Here's the code snippet from my App component: <template> <Loading :message="Importing"></ ...

Tally the number of sub-labels associated with each main label

In my Angular 9 application, I am looking to separate an array based on the lable field. Within each separated array, I would like to determine the count based on the subLable field. This is the array I am working with: [ {"id":1,"socia ...

Using the v-for directive in Vue.js to loop through an array and display

Looking at the image provided, I am trying to access the content. I attempted to do so using element.comments.content, but it did not seem to work as expected. Here is the snippet of code: <div class="fil-actualites-container"> <div cl ...

Mounting component unsuccessful: template or render function undefined. (located in root component)

I am utilizing browserify and NPM to import vue into my project. var Vue = require('vue'); module.exports = function() { new Vue({ el: '#app', data: { message: 'Hello Vue2!' } }) } Encountering a mount error, I su ...

Material 3 Web Components definitions for SolidJS

Struggling with integrating the official Material 3 Web Components into SolidJS. Visit this link for more information. The main hurdle has been encountering typescript errors despite being able to see the components on the page. In my index.tsx, I'v ...

What sets enum with string values apart from a string type union in TypeScript?

When it comes to defining a variable with a predefined set of values in TypeScript code, there are two approaches - using an enum or using a union. For instance, imagine we have a button with various variants such as primary, secondary, and tertiary. We ...

Error Message: Unexpected Type Error with axios in Vue 3

Trying to implement axios in my Vue3 project for fetching APIs. Here is the code snippet from my component: export default { name: "Step2", data() { return { loading: true; }; }, mounted() { this.loading = false; }, ...