[Vue 警告]:未知自定义元素:<nuxt-link> - 当 运行 开玩笑单元测试时
[Vue warn]: Unknown custom element: <nuxt-link> - When running jest unit tests
问题
我正在使用 nuxt 1.4 和路由,使用 Jest 进行单元测试。我的应用程序没有抛出错误并且似乎运行良好。但是,当 运行 我的单元测试 npm run unit
(开玩笑)时,它会在终端中抛出错误:[Vue warn]: Unknown custom element: <nuxt-link> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
预计
我希望它不会抛出此错误,因为我的应用程序正在运行。
文件
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"
]
}
}
我测试的组件:
<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>
我的测试脚本:
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');
});
...
我试过了
我尝试创建一个 localVue 并按照建议对组件进行存根 in this github comment
我也试过 shallow
/mount
但这似乎也不起作用。
...
import NuxtLink from '../.nuxt/components/nuxt-link.js'
...
TestItem.components = TestItem.components || {};
TestItem.components.NuxtLink = NuxtLink;
const wrapper = shallow(TestItem, {
...
});
...
致获得 Unknow custom element: <router-link>
的任何人
我的问题是,我在创建组件时使用了 mount
而不是 shallow
。
shallow usage:
Like mount, it creates a Wrapper that contains the mounted and
rendered Vue component, but with stubbed child components.
Source: https://vue-test-utils.vuejs.org/en/api/shallow.html
这是一个工作示例
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 "path to nuxt-link.js"
Mycomponent.components.NuxtLink = NuxtLink
- 在你的 jest conf 文件中
transformIgnorePatterns: [
"path to nuxt-link.js"
],
或者您可以在安装选项中添加以下行
mount(Mycomponent, {stubs: ["nuxt-link"]})
这就是我摆脱恼人警告的方法:
包括 RouterLinkStub,例如:
import { shallowMount, createLocalVue, RouterLinkStub } from '@vue/test-utils';
将 NuxtLink 存根映射到 RouterLinkStub
const wrapper = shallowMount(TestItem, {
...
stubs: {
NuxtLink: RouterLinkStub
}
})
如果您正在检查 nuxt-link 文本或其他内容,请更改:
const link = wrapper.find('nuxt-link');
到
const link = wrapper.find(RouterLinkStub);
在 https://onigra.github.io/blog/2018/03/19/vue-test-utils-router-link-stub/
上找到了这个金币
幸好你不需要懂日语就可以阅读代码...
我设法使用这个 workaround for 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
})
})
我有:
// path: ./test/jest.setup.js
import Vue from 'vue'
import VueTestUtils from '@vue/test-utils'
// Mock Nuxt components
VueTestUtils.config.stubs['nuxt-link'] = '<a><slot /></a>'
VueTestUtils.config.stubs['no-ssr'] = '<span><slot /></span>'
和
// path: ./jest.config.js
module.exports = {
// ... other stuff
setupFilesAfterEnv: ['./test/jest.setup.js']
}
...这解决了我在 nuxt 应用程序中的所有玩笑测试
尽管提供的答案可能有效。我最终使用的是 based on this guide
const wrapper = mount(TestItem, {
propsData: { item },
localVue,
store,
stubs: {
NuxtLink: true,
// Any other component that you want stubbed
},
});
// test/jestSetup.js
import Vue from 'vue'
import Vuetify from 'vuetify'
import { config } from '@vue/test-utils'
Vue.use(Vuetify)
config.stubs.NuxtLink = { template: '<a><slot /></a>' }
问题
我正在使用 nuxt 1.4 和路由,使用 Jest 进行单元测试。我的应用程序没有抛出错误并且似乎运行良好。但是,当 运行 我的单元测试 npm run unit
(开玩笑)时,它会在终端中抛出错误:[Vue warn]: Unknown custom element: <nuxt-link> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
预计
我希望它不会抛出此错误,因为我的应用程序正在运行。
文件
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"
]
}
}
我测试的组件:
<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>
我的测试脚本:
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');
});
...
我试过了
我尝试创建一个 localVue 并按照建议对组件进行存根 in this github comment
我也试过 shallow
/mount
但这似乎也不起作用。
...
import NuxtLink from '../.nuxt/components/nuxt-link.js'
...
TestItem.components = TestItem.components || {};
TestItem.components.NuxtLink = NuxtLink;
const wrapper = shallow(TestItem, {
...
});
...
致获得 Unknow custom element: <router-link>
我的问题是,我在创建组件时使用了 mount
而不是 shallow
。
shallow usage:
Like mount, it creates a Wrapper that contains the mounted and rendered Vue component, but with stubbed child components.
Source: https://vue-test-utils.vuejs.org/en/api/shallow.html
这是一个工作示例
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 "path to nuxt-link.js"
Mycomponent.components.NuxtLink = NuxtLink
- 在你的 jest conf 文件中
transformIgnorePatterns: [
"path to nuxt-link.js"
],
或者您可以在安装选项中添加以下行
mount(Mycomponent, {stubs: ["nuxt-link"]})
这就是我摆脱恼人警告的方法:
包括 RouterLinkStub,例如:
import { shallowMount, createLocalVue, RouterLinkStub } from '@vue/test-utils';
将 NuxtLink 存根映射到 RouterLinkStub
const wrapper = shallowMount(TestItem, {
...
stubs: {
NuxtLink: RouterLinkStub
}
})
如果您正在检查 nuxt-link 文本或其他内容,请更改:
const link = wrapper.find('nuxt-link');
到
const link = wrapper.find(RouterLinkStub);
在 https://onigra.github.io/blog/2018/03/19/vue-test-utils-router-link-stub/
上找到了这个金币幸好你不需要懂日语就可以阅读代码...
我设法使用这个 workaround for 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
})
})
我有:
// path: ./test/jest.setup.js
import Vue from 'vue'
import VueTestUtils from '@vue/test-utils'
// Mock Nuxt components
VueTestUtils.config.stubs['nuxt-link'] = '<a><slot /></a>'
VueTestUtils.config.stubs['no-ssr'] = '<span><slot /></span>'
和
// path: ./jest.config.js
module.exports = {
// ... other stuff
setupFilesAfterEnv: ['./test/jest.setup.js']
}
...这解决了我在 nuxt 应用程序中的所有玩笑测试
尽管提供的答案可能有效。我最终使用的是 based on this guide
const wrapper = mount(TestItem, {
propsData: { item },
localVue,
store,
stubs: {
NuxtLink: true,
// Any other component that you want stubbed
},
});
// test/jestSetup.js
import Vue from 'vue'
import Vuetify from 'vuetify'
import { config } from '@vue/test-utils'
Vue.use(Vuetify)
config.stubs.NuxtLink = { template: '<a><slot /></a>' }