Reputation: 539
I'm using vue test utils to test a component and getting this error trying to test a text. Cannot call text on an empty DOMWrapper.
UPDATED CODE. getting " RangeError: Maximum call stack size exceeded" in atable.spec.ts test.
atable.spec.ts
import ATable from "../components/ATable.vue";
import { IPatientResponse } from "@/types/patients";
import { shallowMount, RouterLinkStub } from "@vue/test-utils";
it("renders proper texts.", () => {
const wrapper = shallowMount(ATable, {
props: {
patients: [
{
id: 1,
firstName: "arpit",
lastName: "satyal",
email: "[email protected]",
contact: "12345",
address: "ktm",
dob: "1998-07-29",
allergies: ["Pet allergies"],
},
] as IPatientResponse[],
},
stubs: {
RouterLink: RouterLinkStub,
},
scopedSlots: {
bodyCell: `
<template slot-scope="{ column, record }" v-if="column.key === 'firstName'">
<router-link :to="{ name: 'PatientProfile', params: { id: record.id } }">
<div id="test-patient">{{ record.firstName }} {{ record.lastName }}</div>
</router-link>
</template>`,
}
});
const patientNameSelector = wrapper.find("#test-patient");
// see if the message renders
expect(patientNameSelector.text()).toEqual("arpit satyal");
});
atable.vue refactored the table component to be it's own component. it now recieves props from dashboard component.
<!-- eslint-disable vue/multi-word-component-names -->
<template>
<section>
<a-table :columns="columns" :data-source="patients" :pagination="false">
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'firstName'">
<router-link :to="{ name: 'PatientProfile', params: { id: record.id } }">
<span id="test-patient">{{ record.firstName }} {{ record.lastName }}</span>
</router-link>
</template>
<template v-else-if="column.key === 'specialAttention'">
<span class="pointer">
<EyeOutlined
v-if="record.specialAttention"
@click="markAsSpecial(record, false)"
class="iconStyle"
/>
<EyeInvisibleOutlined
v-else
@click="markAsSpecial(record, true)"
class="iconStyle"
/>
</span>
</template>
<template v-else-if="column.key === 'action'">
<span class="pointer">
<router-link :to="{ name: 'UpdatePatient', params: { id: record.id } }">
<EditOutlined style="margin-right: 10px" class="iconStyle" />
</router-link>
<a-divider type="vertical" />
<DeleteOutlined @click="deletePatient(record.id)" class="iconStyle" />
<a-divider type="vertical" />
</span>
</template>
</template>
</a-table>
</section>
</template>
<script lang="ts">
import {
EditOutlined,
DeleteOutlined,
EyeInvisibleOutlined,
EyeOutlined,
} from "@ant-design/icons-vue";
import { defineComponent } from "@vue/runtime-core";
const columns = [
{
title: "Name",
dataIndex: "firstName",
key: "firstName",
align: "center",
},
{
title: "Contact",
dataIndex: "contact",
key: "contact",
align: "center",
},
{
title: "Address",
dataIndex: "address",
key: "address",
align: "center",
},
{
title: "DOB",
key: "dob",
dataIndex: "dob",
align: "center",
},
{
title: "Special Attention",
key: "specialAttention",
align: "center",
},
{
title: "Actions",
key: "action",
align: "center",
},
];
export default defineComponent({
props: ["deletePatient", "markAsSpecial", "patients"],
components: {
EditOutlined,
DeleteOutlined,
EyeInvisibleOutlined,
EyeOutlined,
},
data() {
return {
columns,
};
},
});
</script>
Upvotes: 2
Views: 12378
Reputation: 1321
You are testing Dashboard component and trying to check that ATable (<a-table>
) component rendered slot content that was passed to it. This is wrong.
Considering ATable component all you should check while testing Dashboard component is that the ATable component just was rendered. That's it.
// In Dashboard.spec.js
it("renders ATable component.", () => {
const ATableStub = {
template: '<div>ATableStub</div>'
}
const wrapper = shallowMount(Dashboard, {
stubs: {
ATable: ATableStub
},
data() {
return {
patients: [
{
id: 1,
firstName: "arpit",
lastName: "satyal",
email: "[email protected]",
contact: "12345",
address: "ktm",
dob: "1998-07-29",
allergies: ["Pet allergies"],
},
] as IPatientResponse[],
};
},
});
wrapper.findComponent(ATableStub).exists.toBe(true);
});
});
You should leave testing ATable's slot content to tests for ATable component, not Dashboard component.
// In ATable.spec.js
import { shallowMount, RouterLinkStub } from '@vue/test-utils'
it("renders proper texts.", () => {
const wrapper = shallowMount(ATable, {
stubs: {
RouterLink: RouterLinkStub
},
scopedSlots: {
bodyCell: `
<template slot-scope="{ column, record }" v-if="column.key === 'firstName'">
<router-link :to="{ name: 'PatientProfile', params: { id: record.id } }">
<div id="test-patient">{{ record.firstName }} {{ record.lastName }}</div>
</router-link>
</template>`
},
data() {
return {
patients: [
{
id: 1,
firstName: "arpit",
lastName: "satyal",
email: "[email protected]",
contact: "12345",
address: "ktm",
dob: "1998-07-29",
allergies: ["Pet allergies"],
},
] as IPatientResponse[],
};
},
});
const patientNameSelector = wrapper.find("#test-patient");
// see if the message renders
expect(patientNameSelector.text()).toEqual("arpit satyal");
});
});
Upvotes: 0