具有vue-test-utils和Jest失败的Vue.js单元测试用例

时间:2018-08-21 15:13:25

标签: vue.js jestjs vuetify.js vue-test-utils

使用vue-cli 3,我开始学习Jest的单元测试

我为最初的Heading组件编写了第一个规范

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" alt="Logo-Choro-des-Charentes" height="200">
            <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)

2 个答案:

答案 0 :(得分:0)

在这个特定的cas中,错误来自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"
},

答案 1 :(得分:0)

另一种可能的解决方案是将其添加到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 = {};

第一个模拟所有文件资源(图像和媒体),第二个模拟样式文件。