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.
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 ...
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
})
})
J'ai ajouté ci-dessous des lignes de code pour que cela fonctionne.
Dans votre fichier de test
import NuxtLink from "path to nuxt-link.js"
Mycomponent.components.NuxtLink = NuxtLink
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"]})
À 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');
});
});
});
...
import NuxtLink from '../.nuxt/components/nuxt-link.js'
...
TestItem.components = TestItem.components || {};
TestItem.components.NuxtLink = NuxtLink;
const wrapper = shallow(TestItem, {
...
});
...