【问题标题】:Vue Karma Mocha Unit Test undefined is not a constructor querySelectorVue Karma Mocha 单元测试 undefined 不是构造函数 querySelector
【发布时间】:2020-04-05 17:48:53
【问题描述】:

我为一个名为 badge.vue 的 vue 文件创建了一个新的单元测试。运行时出现以下错误:

badge.vue
    ✗ has zero badges
    undefined is not a constructor (evaluating 'vm.$el.querySelector('.badge')')

    ✗ has a trending badge
    expected null to not equal null

我认为“hasBadge”功能是某种原因。因为当我将它移动到子 div 时,“有零徽章”检查通过但趋势徽章仍然失败。

我有什么遗漏吗?

我正在使用: 业力 v1.7.1

PhantomJS 2.1.1

摩卡

徽章.vue

<template>
  <div v-if="hasBadge" class="badge">
    <icon-base :iconColor="iconColor" :icon-name="iconName"><component v-if="iconName" :is="iconName"></component></icon-base>
    <div class="badge-copy" v-bind:style="iconColorObj">{{badgeCopy}}</div>
  </div>
</template>

<script>
import iconBase from '../icon_base/icon_base';
import iconTrending from '../icons/icon_trending';
import iconClock from '../icons/icon_clock';
import iconEye from '../icons/icon_eye';
import iconTrophy from '../icons/icon_trophy';
import iconStar from '../icons/icon_star';
export default {
  components: {
    iconBase,
    iconTrending,
    iconClock,
    iconEye,
    iconTrophy,
    iconStar,
  },
  data() {
    return {
      iconMap: {
        TRENDING: 'icon-trending',
        ALMOST_GONE: 'icon-clock',
        TOP_SELLER: 'icon-star',
        RECENTLY_VIEWED: 'icon-eye',
        DOORBUSTER: 'icon-trophy',
      },
    };
  },
  props: [
    'deal',
    'toStartCase',
  ],
  computed: {
    hasBadge() {
      const deal = this.deal;
      return deal.badges
        && deal.badges.length > 0
        && deal.badges[0]
        && deal.badges[0].badgeType
        && deal.badges[0].text;
    },
    iconName() {
      const iconMap = this.iconMap;
      const deal = this.deal;
      const badgeType = deal.badges[0].badgeType.toUpperCase();
      if (!iconMap[badgeType]) {
        return undefined;
      }
      return iconMap[badgeType];
    },
    badgeCopy() {
      const deal = this.deal;
      const badgeText = deal.badges[0].text;
      return this.toStartCase &&
        this.toStartCase(badgeText.toLowerCase());
    },
    hasIconColor() {
      const deal = this.deal;
      return deal.badges
        && deal.badges[0]
        && deal.badges[0].primaryColor;
    },
    iconColor() {
      const deal = this.deal;
      if (this.hasIconColor) {
        return deal.badges[0].primaryColor;
      }
      return '#6650D7';
    },
    iconColorObj() {
      return { color: this.iconColor };
    },
  },
};
</script>

<style scoped>
.badge svg {
  display: inline-block;
  vertical-align: baseline;
}
.badge svg path {
  margin: 0 auto;
  width: 12px;
}
.badge-copy {
  color: iconColor;
}
</style>

badge.spec.js

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

describe('badge.vue', () => {

  /* Badges */
  it('has zero badges', () => {
    const vm = new Vue({
      el: document.createElement('div'),
      data: {
        content: {
          rapi: [
            {
              "badges": [],
            }
          ],
        },
      },
      components: {
        badge
      },
      template: '<badge :deal="content.rapi[0]" :toStartCase="toStartCase" ></badge>',
    });
    expect(vm.$el.querySelector('.badge')).to.equal(null);
  });

  it('has a trending badge', () => {
    const vm = new Vue({
      el: document.createElement('div'),
      data: {
        content: {
          rapi: [
            {
              "badges": [
                {
                  "uuid": "84fbb816-3fec-4693-b0a6-ec2f9fb4e400",
                  "primaryColor": "#6650D7E6",
                  "text": "TRENDING",
                  "secondaryColor": "#FFFFFFFF",
                  "badgeType": "TRENDING"
                }
              ],
            },
          ],
        },
      },
      components: {
        badge
      },
      template: '<badge :deal="content.rapi[0]" ></badge>',
    });
    expect(vm.$el.querySelector('.badge')).to.not.equal(null);
    expect(vm.$el.querySelector('.badge-copy').innerText).to.equal('Trending');
  });
});

【问题讨论】:

    标签: javascript vue.js phantomjs mocha.js karma-runner


    【解决方案1】:

    事实证明,在做出任何断言之前,我需要先使用 Vue.nextTick(),然后使用断言,最后使用 done()。

    Source

    徽章.spec.js

    import Vue from "vue";
    import badge from "./badge";
    
    describe('badge.vue', () => {
    
      /* Badges */
      it('has zero badges', () => {
        const vm = new Vue({
          el: document.createElement('div'),
          data: {
            content: {
              rapi: [
                {
                  "badges": [],
                }
              ],
            },
          },
          components: {
            badge
          },
          template: '<badge :deal="content.rapi[0]" ></badge>',
        });
        Vue.nextTick(() => {
          expect(vm.$el.querySelector('.badge-copy')).to.equal(null);
          done();
        });
      });
    
      it('has a trending badge', () => {
        const vm = new Vue({
          el: document.createElement('div'),
          data: {
            content: {
              rapi: [
                {
                  "badges": [
                    {
                      "uuid": "84fbb816-3fec-4693-b0a6-ec2f9fb4e400",
                      "primaryColor": "#6650D7E6",
                      "text": "TRENDING",
                      "secondaryColor": "#FFFFFFFF",
                      "badgeType": "TRENDING"
                    }
                  ],
                },
              ],
            },
          },
          components: {
            badge
          },
          template: '<badge :deal="content.rapi[0]" ></badge>',
        });
        Vue.nextTick(() => {
          expect(vm.$el.querySelector('.badge')).to.not.equal(null);
          expect(vm.$el.querySelector('.badge-copy').innerText).to.equal('Trending');
          done();
        });
      });
    });
    

    【讨论】:

      猜你喜欢
      • 2016-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-12
      • 2019-02-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多