Home  >  Q&A  >  body text

Vuejs unit test issue unable to call text on empty DOMWrapper

I'm using vue test utils to test a component and got this error when trying to test text. Unable to call text on empty DOMWrapper.

Updated code. "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: "arpited7@gmail.com",
          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");
});

Table view Refactor the table component into its own component. It now receives props from the 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>


P粉204136428P粉204136428353 days ago654

reply all(1)I'll reply

  • P粉697408921

    P粉6974089212023-11-01 13:16:58

    You are testing the Dashboard component and trying to check that the ATable () component renders the slot content passed to it. This is wrong. Considering the ATable component, what you should check when testing the Dashboard component is whether the ATable component just 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: "arpited7@gmail.com",
                  contact: "12345",
                  address: "ktm",
                  dob: "1998-07-29",
                  allergies: ["Pet allergies"],
                },
              ] as IPatientResponse[],
            };
          },
        });
    wrapper.findComponent(ATableStub).exists.toBe(true);
      });
    });

    You should leave testing the slot contents of ATable to test the ATable component, not the 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: "arpited7@gmail.com",
                  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");
      });
    });

    reply
    0
  • Cancelreply