@vue/test-utils 中的 mount() 和 shallowMount() 抛出 TypeError: Cannot read property 'components' of undef

Posted

技术标签:

【中文标题】@vue/test-utils 中的 mount() 和 shallowMount() 抛出 TypeError: Cannot read property \'components\' of undefined【英文标题】:mount() and shallowMount() from @vue/test-utils throw TypeError: Cannot read property 'components' of undefined@vue/test-utils 中的 mount() 和 shallowMount() 抛出 TypeError: Cannot read property 'components' of undefined 【发布时间】:2020-07-18 07:43:59 【问题描述】:

我正在尝试为我的 Vue 应用程序设置单元测试,但是每次我运行测试时,mount 或 shallowMount 函数都会给我一个 TypeError: Cannot read property 'components' of undefined 错误。我尝试了@vue/test-utils 版本 1.0.0-beta.32、1.0.0-beta.31 和 1.0.0-beta.27 但无济于事。

错误信息:

 ActuatorController
    ✕ is a Vue instance (24ms)

  ● ActuatorController › is a Vue instance

    TypeError: Cannot read property 'components' of undefined

       5 | 
       6 | beforeEach(() => 
    >  7 |   wrapper = mount(ActuatorController);
         |             ^
       8 | );
       9 | 
      10 | afterEach(() => 

      at createInstance (node_modules/@vue/test-utils/dist/vue-test-utils.js:2537:22)
      at mount (node_modules/@vue/test-utils/dist/vue-test-utils.js:13525:18)
      at Object.<anonymous> (apps/actuator_controller/static/actuator_controller/__tests__/ActuatorController.test.js:7:13)

  ● ActuatorController › is a Vue instance

    TypeError: Cannot read property 'isVueInstance' of undefined

      14 | describe("ActuatorController", () => 
      15 |   test("is a Vue instance", () => 
    > 16 |     expect(wrapper.isVueInstance()).toBeTruthy();
         |                    ^
      17 |   );
      18 | );
      19 | 

      at Object.<anonymous> (apps/actuator_controller/static/actuator_controller/__tests__/ActuatorController.test.js:16:20)

  ● ActuatorController › is a Vue instance

    TypeError: Cannot read property 'destroy' of undefined

       9 | 
      10 | afterEach(() => 
    > 11 |   wrapper.destroy();
         |           ^
      12 | );
      13 | 
      14 | describe("ActuatorController", () => 

      at Object.<anonymous> (apps/actuator_controller/static/actuator_controller/__tests__/ActuatorController.test.js:11:11)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        20.601s

这是我的 package.json

  "name": "igp-package",
  "version": "1.0.0",
  "scripts": 
    "build": "webpack",
    "test": "jest"
  ,
  "dependencies": 
    "lodash": "^4.17.15",
    "mxgraph": "^4.1.0",
    "vue": "^2.6.11",
    "vuetify": "^2.2.15"
  ,
  "devDependencies": 
    "@babel/core": "^7.8.7",
    "@vue/babel-preset-app": "^4.2.3",
    "@vue/test-utils": "^1.0.0-beta.32",
    "babel-core": "^7.0.0-bridge.0",
    "babel-eslint": "^10.1.0",
    "babel-jest": "^25.2.4",
    "babel-loader": "^8.0.6",
    "css-loader": "^3.2.0",
    "deepmerge": "^4.2.2",
    "eslint": "^6.8.0",
    "eslint-config-prettier": "^6.10.1",
    "eslint-loader": "^3.0.3",
    "eslint-plugin-jest": "^23.8.2",
    "eslint-plugin-prettier": "^3.1.2",
    "eslint-plugin-vue": "^6.2.2",
    "fibers": "^4.0.2",
    "file-loader": "^4.3.0",
    "flush-promises": "^1.0.2",
    "jest": "^25.2.4",
    "jest-transform-stub": "^2.0.0",
    "jest-serializer-vue": "^2.0.2",
    "json-loader": "^0.5.7",
    "prettier": "^2.0.2",
    "sass": "^1.26.2",
    "sass-loader": "^8.0.2",
    "style-loader": "^1.0.0",
    "vue-cli-plugin-webpack-bundle-analyzer": "~2.0.0",
    "vue-jest": "^3.0.5",
    "vue-loader": "^15.9.0",
    "vue-style-loader": "^4.1.2",
    "vue-template-compiler": "^2.6.11",
    "vuetify-loader": "^1.4.3",
    "webpack": "^4.41.2",
    "webpack-bundle-analyzer": "^3.6.1",
    "webpack-cli": "^3.3.10"
  

我的 jest.config.js

module.exports = 
  verbose: true,
  moduleFileExtensions: ["js", "jsx", "json", "vue"],
  transform: 
    "^.+\\.vue$": "vue-jest",
    "^.+\\.(js|jsx)?$": "babel-jest",
  ,
  snapshotSerializers: ["jest-serializer-vue"],
  testMatch: ["**/__tests__/*.test.(js|jsx|ts|tsx)"],
  collectCoverage: false,
  collectCoverageFrom: ["**/*.js,vue", "!**/node_modules/**"],
;

这里是测试文件:

import  mount  from "@vue/test-utils";
import  ActuatorController  from "../Vue/ActuatorController.vue";

let wrapper;

beforeEach(() => 
  wrapper = mount(ActuatorController);
);

afterEach(() => 
  wrapper.destroy();
);

describe("ActuatorController", () => 
  test("is a Vue instance", () => 
    expect(wrapper.isVueInstance()).toBeTruthy();
  );
);

最后是用于测试的组件:

<template>
  <div>
    <h1>Title</h1>
  </div>
</template>

<script>
export default 
  name: "ActuatorController",
;
</script>

<style scoped></style>

我希望这是所有必要的信息。在此先感谢您为帮助我所做的努力:)

干杯, 尼可

【问题讨论】:

【参考方案1】:

该错误表示mount 尝试读取ActuatorControllercomponents 属性并失败。

组件是Vue单文件组件中的默认导出,而ActuatorController被命名为导入且未定义。

应该是:

import ActuatorController from "../Vue/ActuatorController.vue";

【讨论】:

以上是关于@vue/test-utils 中的 mount() 和 shallowMount() 抛出 TypeError: Cannot read property 'components' of undef的主要内容,如果未能解决你的问题,请参考以下文章

@vue/test-utils 未知的自定义元素:<router-view>

Vue test-utils 如何使用 vuetify 测试导航栏按钮

Vue3中全局Api改为应用实例的相关变更

Vue 开发实战生态篇 # 25:单元测试的重要性及其使用

Jest + Coverage + VueJs 如何覆盖 vue 方法?

单元测试 Vue 插件