带有 vue-test-utils 和 Jest 的 Vue.js 单元测试用例失败
Posted
技术标签:
【中文标题】带有 vue-test-utils 和 Jest 的 Vue.js 单元测试用例失败【英文标题】:Vue.js unit test cases with vue-test-utils and Jest failing 【发布时间】:2019-01-27 19:48:57 【问题描述】:使用 vue-cli 3,我开始学习用 Jest 进行单元测试
我为我的初始标题组件编写了我的第一个规范
import shallowMount from "@vue/test-utils";
import Heading from "@/components/Home/Heading.vue";
describe("Heading.vue", () =>
it("should contains default heading", () =>
// when
const wrapper = shallowMount(Heading);
// then
const heading = wrapper.find('h1');
expect(heading.text()).toContain('In the heart of Charentes...')
);
);
但我在 y 组件 (??,) 中遇到语法错误
无效或意外的令牌
vue-cli-service test:unit
FAIL tests/unit/Heading.spec.js (16.815s)
Heading.vue
✕ should contains default heading (215ms)
● Heading.vue › should contains default heading
/Users/yves/Developments/WIP/VUE.JS-cli-3/3-chocha-home-content/chocha/src/assets/images/hero.jpeg:1 ("Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest)����
^
SyntaxError: Invalid or unexpected token
124 | .primaryInversed
125 | background-color: white !important;
> 126 | border-color: #464898 !important;
| ^
127 | color: #464898 !important;
128 | .icon
129 | color: #464898 !important;
at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:403:17)
我不明白为什么......(我正在关注来自octo talks的小嘟嘟声
这是我的组件
<template>
<section id='heading'>
<v-parallax :src="require('@/assets/images/hero.jpeg')">
<v-layout column align-center justify-center>
<img src="@/assets/images/logo.png" >
<h1 class="mb-2 display-1 text-xs-center"> $t('lang.views.home.heading.header1') </h1>
<h2 class="mb-2 display-1 text-xs-center"> $t('lang.views.home.heading.header2') </h2>
<div class="subheading mb-3 text-xs-center"> $t('lang.views.home.heading.subheading') </div>
<v-btn round v-if="!listening" @click="startAudioPlayer()" class="primary" large href="#"> $t('lang.views.home.heading.btn__listen')
<v-icon right>play_arrow</v-icon>
</v-btn>
<v-btn round v-else @click="stopAudioPlayer()" class="primaryInversed" large href="#"> $t('lang.views.home.heading.btn__stop')
<v-icon right>pause_circle_outline</v-icon>
</v-btn>
<audioplayer id="audioplayer" v-if="audioPlayer" :autoPlay="shouldPlay" :file="audioFile" :canPlay="audioReady" :ended="audioFinish"></audioplayer>
</v-layout>
</v-parallax>
<div id='content'>
<v-layout row wrap class='my-5' >
<v-flex xs12 sm4>
<v-card class='elevation-0'>
<v-card-text class="text-xs-center">
<v-icon x-large class="">group</v-icon>
</v-card-text>
<v-card-title primary-title class="layout justify-center">
<div class="headline text-xs-center" v-html="$t('lang.views.home.heading.card1__title')"></div>
</v-card-title>
<v-card-text v-html="$t('lang.views.home.heading.card1__content')"></v-card-text>
</v-card>
</v-flex>
<v-flex xs12 sm4>
<v-card class='elevation-0'>
<v-card-text class='text-xs-center'>
<v-icon x-large class="">audiotrack</v-icon>
</v-card-text>
<v-card-title primary-title class="layout justify-center">
<div class="headline" v-html="$t('lang.views.home.heading.card2__title')"></div>
</v-card-title>
<v-card-text v-html="$t('lang.views.home.heading.card2__content')"></v-card-text>
</v-card>
</v-flex>
<v-flex xs12 sm4>
<v-card class='elevation-0'>
<v-card-text class='text-xs-center'>
<v-icon x-large class="">tap_and_play</v-icon>
</v-card-text>
<v-card-title primary-title class="layout justify-center">
<div class="headline text-xs-center" v-html="$t('lang.views.home.heading.card3__title')"></div>
</v-card-title>
<v-card-text v-html="$t('lang.views.home.heading.card3__content')"></v-card-text>
</v-card>
</v-flex>
</v-layout>
</div>
</section>
</template>
<script>
import AudioPlayer from "@/components/Home/AudioPlayer.vue";
// import mapGetters from 'vuex'
export default
name: "Heading",
data()
return
listening: false,
file: "ultimo_desejo",
audioPlayer: false,
audioPlayerShouldPlay: true // autoplay
;
,
components:
audioplayer: AudioPlayer
,
computed:
// ...mapGetters(['webpSupport']),
shouldPlay()
return this.audioPlayerShouldPlay;
,
audioFile()
return require("@/assets/audio/" + this.file + ".mp3");
,
methods:
audioReady()
// console.log('You see this means audio can start.')
,
audioFinish()
// console.log('You see this means audio finish.')
this.listening = false;
this.audioPlayer = false;
,
showAudioPlayer()
this.audioPlayer = true;
,
startAudioPlayer()
this.listening = true;
this.audioPlayer = true;
,
stopAudioPlayer()
this.listening = false;
this.audioPlayer = false;
,
mounted()
// console.log('HEADING webp format support: ', this.webpSupport)
,
beforeMount()
this.playerAutoPlay = this.autoPlay; // save props data to itself's data and deal with it
;
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
#audioplayer
display: none; // hide the autoplayer !
.btn__content .icon
color: white !important;
.primaryInversed
background-color: white !important;
border-color: #464898 !important;
color: #464898 !important;
.icon
color: #464898 !important;
</style>
更新
这是完整的 console.log 错误输出
> vue-cli-service test:unit
FAIL tests/unit/Heading.spec.js (8.158s)
Heading.vue
✕ should contains default heading (226ms)
● Heading.vue › should contains default heading
/Users/yves/Developments/WIP/VUE.JS-cli-3/3-chocha-home-content/chocha/src/assets/images/hero.jpeg:1
("Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest)����
^
SyntaxError: Invalid or unexpected token
124 | .primaryInversed
125 | background-color: white !important;
> 126 | border-color: #464898 !important;
| ^
127 | color: #464898 !important;
128 | .icon
129 | color: #464898 !important;
at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:403:17)
at Proxy.render (src/components/Home/Heading.vue:126:186)
at VueComponent.Vue._render (node_modules/vue/dist/vue.runtime.common.js:4542:22)
at VueComponent.updateComponent (node_modules/vue/dist/vue.runtime.common.js:2786:21)
at Watcher.get (node_modules/vue/dist/vue.runtime.common.js:3140:25)
at new Watcher (node_modules/vue/dist/vue.runtime.common.js:3129:12)
console.error node_modules/vue/dist/vue.runtime.common.js:589
[Vue warn]: Error in config.errorHandler: "SyntaxError: Invalid or unexpected token"
console.error node_modules/vue/dist/vue.runtime.common.js:1739
/Users/yves/Developments/WIP/VUE.JS-cli-3/3-chocha-home-content/chocha/src/assets/images/hero.jpeg:1
("Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest)����
^
SyntaxError: Invalid or unexpected token
at ScriptTransformer._transformAndBuildScript (/Users/yves/Developments/WIP/VUE.JS-cli-3/3-chocha-home-content/chocha/node_modules/jest-runtime/build/script_transformer.js:403:17)
at ScriptTransformer.transform (/Users/yves/Developments/WIP/VUE.JS-cli-3/3-chocha-home-content/chocha/node_modules/jest-runtime/build/script_transformer.js:448:19)
at Runtime._execModule (/Users/yves/Developments/WIP/VUE.JS-cli-3/3-chocha-home-content/chocha/node_modules/jest-runtime/build/index.js:640:53)
at Runtime.requireModule (/Users/yves/Developments/WIP/VUE.JS-cli-3/3-chocha-home-content/chocha/node_modules/jest-runtime/build/index.js:376:14)
at Runtime.requireModuleOrMock (/Users/yves/Developments/WIP/VUE.JS-cli-3/3-chocha-home-content/chocha/node_modules/jest-runtime/build/index.js:463:19)
at Proxy.render (/Users/yves/Developments/WIP/VUE.JS-cli-3/3-chocha-home-content/chocha/src/components/Home/Heading.vue:126:186)
at VueComponent.Vue._render (/Users/yves/Developments/WIP/VUE.JS-cli-3/3-chocha-home-content/chocha/node_modules/vue/dist/vue.runtime.common.js:4542:22)
at VueComponent.updateComponent (/Users/yves/Developments/WIP/VUE.JS-cli-3/3-chocha-home-content/chocha/node_modules/vue/dist/vue.runtime.common.js:2786:21)
at Watcher.get (/Users/yves/Developments/WIP/VUE.JS-cli-3/3-chocha-home-content/chocha/node_modules/vue/dist/vue.runtime.common.js:3140:25)
at new Watcher (/Users/yves/Developments/WIP/VUE.JS-cli-3/3-chocha-home-content/chocha/node_modules/vue/dist/vue.runtime.common.js:3129:12)
console.error node_modules/vue/dist/vue.runtime.common.js:589
[Vue warn]: Error in render: "SyntaxError: Invalid or unexpected token"
found in
---> <Heading>
<Root>
console.error node_modules/vue/dist/vue.runtime.common.js:1739
/Users/yves/Developments/WIP/VUE.JS-cli-3/3-chocha-home-content/chocha/src/assets/images/hero.jpeg:1
("Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest)����
^
SyntaxError: Invalid or unexpected token
at ScriptTransformer._transformAndBuildScript (/Users/yves/Developments/WIP/VUE.JS-cli-3/3-chocha-home-content/chocha/node_modules/jest-runtime/build/script_transformer.js:403:17)
at ScriptTransformer.transform (/Users/yves/Developments/WIP/VUE.JS-cli-3/3-chocha-home-content/chocha/node_modules/jest-runtime/build/script_transformer.js:448:19)
at Runtime._execModule (/Users/yves/Developments/WIP/VUE.JS-cli-3/3-chocha-home-content/chocha/node_modules/jest-runtime/build/index.js:640:53)
at Runtime.requireModule (/Users/yves/Developments/WIP/VUE.JS-cli-3/3-chocha-home-content/chocha/node_modules/jest-runtime/build/index.js:376:14)
at Runtime.requireModuleOrMock (/Users/yves/Developments/WIP/VUE.JS-cli-3/3-chocha-home-content/chocha/node_modules/jest-runtime/build/index.js:463:19)
at Proxy.render (/Users/yves/Developments/WIP/VUE.JS-cli-3/3-chocha-home-content/chocha/src/components/Home/Heading.vue:126:186)
at VueComponent.Vue._render (/Users/yves/Developments/WIP/VUE.JS-cli-3/3-chocha-home-content/chocha/node_modules/vue/dist/vue.runtime.common.js:4542:22)
at VueComponent.updateComponent (/Users/yves/Developments/WIP/VUE.JS-cli-3/3-chocha-home-content/chocha/node_modules/vue/dist/vue.runtime.common.js:2786:21)
at Watcher.get (/Users/yves/Developments/WIP/VUE.JS-cli-3/3-chocha-home-content/chocha/node_modules/vue/dist/vue.runtime.common.js:3140:25)
at new Watcher (/Users/yves/Developments/WIP/VUE.JS-cli-3/3-chocha-home-content/chocha/node_modules/vue/dist/vue.runtime.common.js:3129:12)
【问题讨论】:
【参考方案1】:在这个特定的案例中,错误来自 hero.jpeg 图像文件。我应该将 jpeg 扩展名添加到 package.json 中的“jest”“transform”块中,该块目前仅转换 jpg 文件。
"transform":
"^.+\\.vue$": "vue-jest",
".+\\.(css|styl|less|sass|scss|png|jpg|jpeg|mp3|ttf|woff|woff2)$": "jest-transform-stub",
"^.+\\.jsx?$": "babel-jest",
"^.+\\.js?$": "babel-jest"
,
【讨论】:
【参考方案2】:另一种可能的解决方案是将其添加到 package.json 文件的“jest”对象的“moduleNameMapper”对象中:
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/test/mocks/fileMock.js",
"\\.(css|scss)$": "<rootDir>/test/mocks/styleMock.js"
fileMock.js 的内容:
module.exports = 'test-file-stub';
styleMock.js 的内容:
module.exports = ;
第一个模拟所有文件资源(图像和媒体),第二个模拟样式文件。
【讨论】:
以上是关于带有 vue-test-utils 和 Jest 的 Vue.js 单元测试用例失败的主要内容,如果未能解决你的问题,请参考以下文章
无法在基于 jest 和 vue-test-utils 的测试项目中使用 vue.js 的 ES6 模块
Vue-test-utils | Jest:如何处理依赖关系?
使用 `vue-test-utils` 和 `jest` 使用 `Created` 钩子进行测试
如何使用 Vue-test-utils 和 Jest 测试 Vuex 突变