web-dev-qa-db-fra.com

[Vue warn]: Élément personnalisé inconnu: <nuxt-link> - Lors de l'exécution de tests unitaires jest

Problème

J'utilise nuxt 1.4 avec le routage en utilisant Jest pour faire des tests unitaires. Mon application ne génère pas d'erreurs et semble fonctionner parfaitement. Cependant, lors de l'exécution de mon test unitaire npm run unit (qui exécute la plaisanterie) il lance une erreur dans le terminal: [Vue warn]: Unknown custom element: <nuxt-link> - did you register the component correctly? For recursive components, make sure to provide the "name" option.

Attendu

Je m'attendrais à ce qu'il ne lance pas cette erreur car mon application fonctionne.

Fichiers

package.json:

{
  "name": "vue-starter",
  "version": "1.0.0",
  "description": "Nuxt.js project",
  "private": true,
  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "start": "nuxt start",
    "generate": "nuxt generate",
    "lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
    "precommit": "npm run lint",
    "test": "npm run lint && npm run unit",
    "unit": "jest",
    "unit:report": "jest --coverage"
  },
  "dependencies": {
    "babel-jest": "^22.4.1",
    "jest-serializer-vue": "^1.0.0",
    "node-sass": "^4.7.2",
    "npm": "^5.7.1",
    "nuxt": "^1.0.0",
    "sass-loader": "^6.0.7",
    "vue-jest": "^2.1.1"
  },
  "devDependencies": {
    "@vue/test-utils": "^1.0.0-beta.12",
    "babel-eslint": "^8.2.1",
    "eslint": "^4.15.0",
    "eslint-friendly-formatter": "^3.0.0",
    "eslint-loader": "^1.7.1",
    "eslint-plugin-vue": "^4.0.0",
    "jest": "^22.4.2"
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not ie <= 8"
  ],
  "jest": {
    "moduleFileExtensions": [
      "js",
      "vue"
    ],
    "transform": {
      "^.+\\.js$": "<rootDir>/node_modules/babel-jest",
      ".*\\.(vue)$": "<rootDir>/node_modules/vue-jest"
    },
    "snapshotSerializers": [
      "<rootDir>/node_modules/jest-serializer-vue"
    ]
  }
}

Le composant que je teste:

<template>
  <div>
    <nuxt-link class="name" :to="{ path: `entity/${item.id}`, params: { id: item.id }}">{{item.name}}</nuxt-link>
    <button class="connect" @click="connect">{{ btnText }}</button>
  </div>
</template>

<script>
  // import nuxtLink from '../.nuxt/components/nuxt-link';

  const connectionStatusMap = [
    'Connect',
    'Connected',
    'Pending',
    'Cancel',
  ];

  export default {
    /*components: {
      'nuxt-link': nuxtLink,
    },*/
    props: {
      item: {
        type: Object
      }
    },
    ...
  }
</script>

Mon script de test:

import TestItem from '../components/TestItem';
import { shallow, mount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
import VueRouter from 'vue-router';

const localVue = createLocalVue()

localVue.use(Vuex)
localVue.use(VueRouter)

...
it(`should show the entity`, () => {
    const wrapper = mount(TestItem, {
      propsData: { item },
      localVue,
      store,
      // stubs: ['nuxt-link'],
    })
    expect(wrapper.find('.name').text()).toBe(item.name);
  });

  it(`should show allow me to connect if I'm not yet connected`, () => {
    const wrapper = shallow(TestItem, {
      propsData: { item },
      localVue,
      store,
      stubs: ['nuxt-link'],
    })
    expect(wrapper.find('.connect').text()).toBe('Connect');
  });
...

J'ai essayé

J'ai essayé de créer un localVue et aussi de couper le composant comme suggéré dans ce commentaire github J'ai également essayé shallow/mount mais cela ne semble pas fonctionner non plus.

13
Anima-t3d

C'est ainsi que j'ai pu me débarrasser de l'avertissement ennuyeux.

Inclure RouterLinkStub, par exemple:

import { shallowMount, createLocalVue, RouterLinkStub } from '@vue/test-utils';

Mapper le stub NuxtLink au RouterLinkStub

const wrapper = shallowMount(TestItem, {
  ... 
  stubs: {
    NuxtLink: RouterLinkStub,
})

Et au cas où vous vérifieriez du texte de lien nuxt ou quelque chose, changez:

const link = wrapper.find('nuxt-link');

à

const link = wrapper.find(RouterLinkStub);

Trouvé cet or sur https://onigra.github.io/blog/2018/03/19/vue-test-utils-router-link-stub/

Heureusement que vous n'avez pas besoin de connaître le japonais pour lire le code ...

5
Kristo J

J'ai réussi à le faire fonctionner en utilisant ceci solution de contournement pour Storybook :

import { mount, createLocalVue } from '@vue/test-utils'
import Component from '@/components/Component.vue'

const localVue = createLocalVue()

localVue.component('nuxt-link', {
  props:   ['to'],
  template: '<a href="#"><slot>NuxtLink</slot></a>',
})

describe('Test Component', () => {

    const wrapper = mount(Component, {
      stubs: ['nuxt-link'],
      localVue
    })
})

1
mstrlaw

J'ai ajouté ci-dessous des lignes de code pour que cela fonctionne.

  1. Dans votre fichier de test

    import NuxtLink from "path to nuxt-link.js"
    
    Mycomponent.components.NuxtLink = NuxtLink
    
  2. Dans votre fichier jest conf

    transformIgnorePatterns: [
       "path to nuxt-link.js"
    ],
    

Ou vous pouvez ajouter la ligne ci-dessous dans les options de montage

mount(Mycomponent, {stubs: ["nuxt-link"]})
0
Chandru C R M

À tous ceux qui obtiennent le Unknow custom element: <router-link>

Mon problème était que j'ai utilisé mount au lieu de shallow lors de la création du composant.

utilisation superficielle:

Comme mount, il crée un wrapper qui contient le composant monté et rendu Vue, mais avec des composants enfants tronqués.

Source: https://vue-test-utils.vuejs.org/en/api/shallow.html

Voici un exemple de travail

import { shallow } from '@vue/test-utils';                               
import ContentCard from '../../components/ContentCard.vue';                                                                           
import NuxtLink from '../../.nuxt/components/nuxt-link';                                                                              

const createComponent = propsData => shallow(ContentCard, { propsData });                                                             

describe('ContentCard', () => {                                                                                                       
  let component;                                                                                                                      

  beforeEach(() => {
    ContentCard.components = ContentCard.components || {};                                                                            
    ContentCard.components.NuxtLink = NuxtLink;                                                                                       
  });   

  describe('Properties', () => {
    it('has an imgSrc property', () => {                                                                                              
      component = createComponent({ imgSrc: 'X' });                                                                                   
      expect(component.props().imgSrc).toBe('X');                                                                                     
    });   
  });     
});
0
Oldenborg
...
import NuxtLink from '../.nuxt/components/nuxt-link.js'

...
TestItem.components = TestItem.components || {};
TestItem.components.NuxtLink = NuxtLink;
const wrapper = shallow(TestItem, {
    ...
});

...
0
xtranophilist