I'm trying to render a component in my Vue unit test with Jest, but I can't seem to get it to work.
The logs say: TypeError: Cannot read property 'length' of null
I've tried other components, and it works fine.
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>
Also ignore the fact that this component isn't done and might not necessarily involve the most relevant use cases for unit tests. I'm just curious to know why this certain component can't be loaded as a Vue instance in my test?
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();
});
});
Has anyone had the same issue? If so, can someone explain to me how you solved it?