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.