无法通过Jest在我的单元测试中渲染Vue组件

问题描述 投票:-1回答:2

我正在尝试使用Jest在Vue单元测试中渲染组件,但似乎无法使其正常工作。

日志说:TypeError: Cannot read property 'length' of null

我已经尝试了其他组件,并且工作正常。

ErrandsListTable.vue

<template>
  <div
    v-if="!error"
    class="flex-table flex-table--white-background flex-table--green-header flex-table--with-dropdown"
    :class="{ loading: loading }"
  >
    <div class="flex-table__row flex-table--header text--level-6">
      <div class="flex-table__cell flex-table__cell--width-3">
        {{ statusHeader }}
      </div>
      <div class="flex-table__cell flex-table__cell--width-3">
        {{ idHeader }}
      </div>
      <div class="flex-table__cell flex-table__cell--width-7">
        {{ descriptionHeader }}
      </div>
      <div class="flex-table__cell flex-table__cell--width-5">
        {{ typeHeader }}
      </div>
      <div class="flex-table__cell flex-table__cell--width-3">
        {{ dateOpenedHeader }}
      </div>
      <div class="flex-table__cell flex-table__cell--width-3">
        {{ dateClosedHeader }}
      </div>
      <div class="flex-table__cell flex-table__cell--width-1" />
    </div>

    <div
      v-for="(errand, index) in sliceArray(errands)"
      :key="!errand.id ? index : errand.id"
    >
      <div
        class="flex-table__row"
        :class="{ 'flex-table__row--closed': index !== selectedErrand }"
        @click="toggleExpanded(index)"
      >
        <div class="flex-table__cell flex-table__cell--width-3">
          {{ errand.status }}
        </div>
        <div class="flex-table__cell flex-table__cell--width-3">
          {{ errand.id }}
        </div>
        <div
          class="flex-table__cell flex-table__cell--width-7 flex-table__cell--show-on-mobile"
          :data-header="descriptionHeader"
        >
          {{ errand.description }}
        </div>
        <div class="flex-table__cell flex-table__cell--width-5">
          {{ errand.type }}
        </div>
        <div
          class="flex-table__cell flex-table__cell--width-3 flex-table__cell--show-on-mobile"
          :data-header="dateOpenedHeader"
        >
          {{ errand.orderDate }}
        </div>
        <div class="flex-table__cell flex-table__cell--width-3">
          {{ errand.deliveryDate }}
        </div>
        <div
          class="flex-table__cell flex-table__cell--width-1 flex-table__cell--dropdown-show-on-mobile"
        >
          <i
            class="icon-angle__small"
            :class="{ 'icon-angle__small--down': selectedErrand === index }"
          />
        </div>
      </div>

      <ErrandsListDetails
        v-if="selectedErrand >= 0 && selectedErrand === index"
        :errand="errand"
        v-bind="$props"
      />
    </div>

    <div
      v-if="errands.length >= numberOfErrandsLoaded"
      class="flex-table--load-more text--level-5"
    >
      <a href="#" @click="loadMore">
        {{ showMoreText }}
        <i class="icon-down" />
      </a>
    </div>
    <div
      v-if="errands.length < 1 && !loading"
      class="flex-table--error text--level-5"
    >
      {{ noCasesText }}
    </div>
    <div v-if="error && !loading" class="flex-table--error text--level-5">
      {{ errorText }}
    </div>
  </div>
</template>

<script>
import _ from "lodash";
import ErrandsListDetails from "./ErrandsListDetails.vue";

export default {
  components: {
    ErrandsListDetails: ErrandsListDetails
  },
  props: {
    componentTitle: {
      type: String,
      default: () => {
        return "";
      }
    },
    showMoreText: {
      type: String,
      default: "Visa fler ärenden"
    },
    statusHeader: {
      type: String,
      default: () => {
        return "Status";
      }
    },
    dateOpenedHeader: {
      type: String,
      default: () => {
        return "Beställt/Anmält";
      }
    },
    dateClosedHeader: {
      type: String,
      default: () => {
        return "Beräknad klar";
      }
    },
    idHeader: {
      type: String,
      default: () => {
        return "Ärendenummer";
      }
    },
    descriptionHeader: {
      type: String,
      default: () => {
        return "Beskrivning";
      }
    },
    typeHeader: {
      type: String,
      default: () => {
        return "Typ";
      }
    },
    fileDetails: {
      type: String,
      default: () => {
        return "Ladda ned beställningen som PDF:";
      }
    },
    commentsDetails: {
      type: String,
      default: () => {
        return "Noteringar";
      }
    },
    wordList: {
      type: String,
      default: () => {
        return "";
      }
    },
    attachment: {
      type: String,
      default: () => {
        return "";
      }
    },
    noCasesText: {
      type: String,
      default: () => {
        return "Det finns inget att visa";
      }
    },
    errorText: {
      type: String,
      default: () => {
        return "Något gick fel";
      }
    },
    createdOnFallback: {
      type: String,
      default: () => {
        return "-";
      }
    },
    closedOnFallback: {
      type: String,
      default: () => {
        return "-";
      }
    },
    errandsCounter: {
      type: Object,
      default: () => {
        return null;
      }
    },
    errands: {
      type: Array,
      default: () => {
        return null;
      }
    },
    loading: {
      type: Boolean,
      default: () => {
        return false;
      }
    }
  },
  data() {
    return {
      selectedErrand: -1,
      error: undefined,
      numberOfErrandsLoaded: 10
    };
  },
  methods: {
    toggleExpanded: function(index) {
      this.selectedErrand = this.selectedErrand === index ? -1 : index;
    },

    loadMore: function(event) {
      event.preventDefault();
      this.numberOfErrandsLoaded += 10;
    },

    sliceArray: function(array) {
      let val = _.orderBy(array, "orderDate", "desc");
      return val.slice(0, this.numberOfErrandsLoaded);
    }
  }
};
</script>

也忽略了以下事实:该组件尚未完成,并且不一定涉及单元测试中最相关的用例。我只是很好奇,为什么不能在测试中将某些组件作为Vue实例加载?

import { shallowMount } from "@vue/test-utils";
import ErrandsListTable from "../ErrandsListTable.vue";

let wrapper;

describe("Errandslist table", () => {
  beforeEach(() => {
    wrapper = shallowMount(ErrandsListTable);
  });

  afterEach(() => {
    wrapper.destroy();
  });
  it("is a Vue instance", () => {
    expect(wrapper.isVueInstance).toBeTruthy();
  });
});

有人遇到过同样的问题吗?如果是这样,有人可以向我解释您如何解决它?

javascript vue.js jest
2个回答
0
投票

errands属性的默认值为null。由于要安装的组件没有任何支撑,因此null的默认值生效。您的模板带有errands.length,这会导致您观察到错误。

要解决该错误,请使用errands prop安装组件:

wrapper = shallowMount(ErrandsListTable, {
  propsData: {
    errands: []
  }
});

0
投票

在您的模板中,您的errands数组为空,因此您无法访问length属性。您要么必须在组件中处理这种情况,要么必须将此属性传递给组件。

设置默认值

errands: {
  type: Array,
  default: () => {
    return [];
  }
}

通过测试时通过默认值

const wrapper = shallowMount(ErrandsListTable, {
  propsData: {
    errands: []
  }
})
expect(wrapper.props().errands.length).toBe(0)
© www.soinside.com 2019 - 2024. All rights reserved.