0

I am testing my vue component that uses vuejs-smart-table

by rendering the headers and rows from head and body slot that is in my vue component.

this is my vue component (it is just a wrapper that wraps vuejs-smart-table and a pagination component):

<template>
  <div class="custom-table-wrapper">
    <div class="table-container" :style="tableContainerStyle">
      <v-table
        :id="id"
        :class="tableClass"
        :data="data"
        :hideSortIcons="true"
        :pageSize="pageSize"
        :filters="filters"
        :currentPage="currentPage"
        :selectionMode="selectionMode"
        :selectedClass="selectedClass"
        @update:currentPage="currentPageChanged"
        @totalPagesChanged="totalPagesChanged"
        @selectionChanged="selectionChanged">
          <template slot="head">
            <slot name="head">
            </slot>
          </template>
          <template slot="body" slot-scope="{displayData}">
            <slot name="body" :displayData="displayData">
            </slot>
          </template>
      </v-table>
    </div>
    <div v-show="showTableFooter" class="paging" id="pagination">
      <smart-pagination
        v-show="totalPages>1"
        :currentPage="currentPage"
        :totalPages="totalPages"
        :maxPageLinks="5"
        @update:currentPage="currentPageChanged"/>
      <div class="footer-action-btns-container">
        <slot name="footer-action-btns">

        </slot>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  props: {
    id: {
      type: String,
      required: true,
    },
    data: {
      type: Array | null,
      default() {
        return [];
      },
    },
    filters: {
      type: Object,
      default() {
        return {};
      },
    },
    tableClass: {
      type: [String, Object],
      default: 'table table-bordered',
    },
    hideSortIcons: {
      type: Boolean,
      default: false,
    },
    pageSize: {
      type: Number,
      default: 20,
    },
    selectionMode: {
      type: String,
      default: 'single',
    },
    selectedClass: {
      type: String,
      default: 'vt-selected',
    },
    tableContainerStyle: {
      type: [String, Object],
      value: undefined,
    },
  },
  data() {
    return {
      totalPages: 0,
      currentPage: 1,
    };
  },
  methods: {
    totalPagesChanged(page) {
      this.totalPages = page;
    },
    currentPageChanged(page) {
      this.currentPage = page;
    },
    selectionChanged($event) {
      this.$emit('selectionChanged', $event);
    },
  },
  computed: {
    showTableFooter() {
      return this.data.length > this.pageSize || this.$slots['footer-action-btns']?.[0];
    },
  },
};
</script>

this is my spec file for testing my vue component:

import { createLocalVue, mount, $createElement } from '@vue/test-utils';
import SmartTable from 'vuejs-smart-table';

import CustomTable from '@/components/custom-table.vue';

const localVue = createLocalVue();
localVue.use(SmartTable);

describe('CustomTable.vue Test', () => {
  let wrapper;
  let data = [
    {
      id: '1',
      first_name: 'user1',
      last_name: 'user1',
    },
    {
      id: '2',
      first_name: 'user2',
      last_name: 'user2',
    },
    {
      id: '3',
      first_name: 'user3',
      last_name: 'user3',
    },
  ];

  beforeEach(() => {
    wrapper = mount(CustomTable, {localVue,
      propsData: {
          data: data,
          id: 'custom-table',
      },
      slots: {
        head: `
          <thead>
            <tr>
              <th>First Name</th>
              <th>Last Name</th>
            </tr>
          </thead>
        `,
        body: `
        <tbody #body="{displayData}">
          <tr v-for="(row, index) in displayData" :key="index">
            <td>{{row.first_name}}</td>
            <td>{{row.last_name}}</td>
          </tr>
        </tbody>
        `
      },
    });
  }); 

  it('renders items from data as rows', () => {
    expect(wrapper).toMatchSnapshot();
  });
});

this is the output of the snapshot:

exports[`CustomTable.vue Test renders items from data as rows 1`] = `
<div class="custom-table-wrapper">
  <div class="table-container">
    <table id="custom-table" class="table table-bordered">
      <thead>
        <tr>
          <th>First Name</th>
          <th>Last Name</th>
        </tr>
      </thead>
      <tbody></tbody>
    </table>
  </div>
  <div id="pagination" class="paging" style="display: none;">
    <nav class="smart-pagination" style="display: none;">
      <ul class="pagination">
        <!---->
        <li class="page-item disabled"><a href="javascript:void(0)" aria-label="Previous" class="page-link"><svg width="16" height="16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
              <path fill="currentColor" d="M34.52 239.03L228.87 44.69c9.37-9.37 24.57-9.37 33.94 0l22.67 22.67c9.36 9.36 9.37 24.52.04 33.9L131.49 256l154.02 154.75c9.34 9.38 9.32 24.54-.04 33.9l-22.67 22.67c-9.37 9.37-24.57 9.37-33.94 0L34.52 272.97c-9.37-9.37-9.37-24.57 0-33.94z"></path>
            </svg></a></li>
        <li class="page-item active"><a href="javascript:void(0)" class="page-link">1</a></li>
        <li class="page-item disabled"><a href="javascript:void(0)" aria-label="Next" class="page-link"><svg width="16" height="16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
              <path fill="currentColor" d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"></path>
            </svg></a></li>
        <!---->
      </ul>
    </nav>
    <div class="footer-action-btns-container"></div>
  </div>
</div>
`;

as you can see the tbody doesnt render any rows here. i have tried using scopedSlots but it just results to more errors.

ephraim lambarte
  • 121
  • 1
  • 11

0 Answers0