[Vue warn]:未知的自定义元素:-< nuxt-link>运行jest单元测试时

z9gpfhce  于 2023-04-27  发布在  Jest
关注(0)|答案(9)|浏览(163)

问题

我使用nuxt 1.4和路由使用Jest进行单元测试。我的应用程序没有抛出错误,似乎工作得很好。但是,当运行我的单元测试npm run unit(运行jest)时,它在终端中抛出一个错误:[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,并按照github评论中的建议对组件进行存根,我还尝试了shallow/mount,但似乎也不起作用。

0lvr5msh

0lvr5msh1#

这就是我如何能够摆脱恼人的警告:
包括RouterLinkStub,例如:

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

将NuxtLink存根Map到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/上找到了这个黄金
好消息是你不需要懂日语就能读懂代码。

i34xakig

i34xakig2#

虽然提供的答案可以工作。我最终使用的是基于这个指南

const wrapper = mount(TestItem, {
  propsData: { item },
  localVue,
  store,
  stubs: {
    NuxtLink: true,
    // Any other component that you want stubbed
  },
});
qyyhg6bp

qyyhg6bp3#

我设法让它工作使用这个解决方案的故事书:

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
    })
})
2ledvvac

2ledvvac4#

我在下面添加了几行代码来使其工作。
1.在您的测试文件中

import NuxtLink from "path to nuxt-link.js"

Mycomponent.components.NuxtLink = NuxtLink

1.在你的jest conf文件里

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

或者您可以在挂载选项中添加下面一行

mount(Mycomponent, {stubs: ["nuxt-link"]})
erhoui1w

erhoui1w5#

我有:

// 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应用程序中的所有jest测试

jm2pwxwz

jm2pwxwz6#

任何人得到Unknow custom element: <router-link>
我的问题是,我在创建组件时使用了mount而不是shallow

浅度使用:

与mount类似,它创建了一个Wrapper,其中包含已挂载和渲染的Vue组件,但带有存根子组件。

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

e0uiprwp7#

...
import NuxtLink from '../.nuxt/components/nuxt-link.js'

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

ou6hu8tu8#

// 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>' }
70gysomp

70gysomp9#

来自Anima-t3 d的公认答案可以工作,但不能解释所有用例。
请注意,下面的解决方案是使用vue test-utils v2为Nuxt 3量身定制的,因此安装选项发生了变化。没有在以前的版本中尝试过。

用例一:

我不需要访问NuxtLink的内部元素。=〉Stubbing是一个很好的选择,所以这导致了Anima-t3 d的答案:

const wrapper = mount(TestItem, {
  props,
  global: {
    stubs: {
      NuxtLink: true,
    },
  },
});

注意:stub也需要为shallowMount显式定义。

用例二:

由于某些原因,我想访问NuxtLink的内部元素。=〉Stubbing不起作用,相反,我们可以在测试文件中定义一个自定义组件:

wrapper = mount(TestItem, {
  props,
  global: {
    components: {
      NuxtLink: {
        template: '<a><slot/></a>',
      },
    },
  },
});

注意:如果你使用的是shallowMount,你仍然需要在stubs中列出NuxtLink并将其设置为false:

wrapper = shallowMount(TestItem, {
  props,
  global: {
    stubs: {
      NuxtLink: false,
    },
    components: {
      NuxtLink: {
        template: '<a><slot/></a>',
      },
    },
  },
});

这是用你为它定义的模板替换NuxtLink。里面使用的html元素被保留,属性(如classes或“to”属性)被自动应用。
这意味着,给定NuxtLink的以下用法

<NuxtLink
  to="www.example.com"
  class="item-class"
><div>ItemContent</div></NuxtLink>

,wrapper.html的输出将是

<a to="www.example.com" class="item-class"><div>ItemContent</div></a>

相关问题