Testing a Vuetify Data Table using Jest for unit testing

I've developed a Vue.js application utilizing Vuetify and I'm currently working on unit testing a component that contains a Vuetify Data Table. The issue arises when trying to populate the table in my unit test, where Axios is mocked with Jest.

Below is the code snippet for the Component:

<template>
  <v-container fluid>
    <v-card>
      <v-card-title>
        Results
        <v-spacer></v-spacer>
        <v-text-field
          v-model="search"
          append-icon="mdi-magnify"
          label="Search"
          single-line
          hide-details
        ></v-text-field>
      </v-card-title>
      <v-data-table
        :headers="headers"
        :items="results"
        :search="search"
        :loading="loading"
        loading-text="Loading results..."
        :custom-sort="customSort"
      >
        <template v-slot:item.startTime="{item}">{{formatDate(item.startTime)}}</template>
        <template v-slot:item.endTime="{item}">{{formatDate(item.endTime)}}</template>
      </v-data-table>
    </v-card>
  </v-container>
</template>

<script>
import axios from 'axios';
import moment from 'moment';

function dateArrayToMoment(date) {
  return moment()
    .year(date[0])
    .month(date[1])
    .date(date[2])
    .hour(date[3])
    .minute(date[4]);
}

export default {
  name: 'ResultsList',
  data() {
    return {
      loading: true,
      search: '',
      headers: [
        { text: 'Task', align: 'start', sortable: false, value: 'title' },
        { text: 'State', value: 'state' },
        { text: 'Start Time', value: 'startTime' },
        { text: 'End Time', value: 'endTime' },
        { text: 'Result', value: 'resultMessage' }
      ],
      results: []
    };
  },
  mounted() {
    this.loadResults();
  },
  methods: {
    async loadResults() {
      try {
        let response = await axios.get('BACKEND_SERVER/results', {});
        this.results = response.data;
        this.loading = false;
        // eslint-disable-next-line no-debugger
      } catch (error) {
        // eslint-disable-next-line no-console
        console.error(error);
        // you can handle different errors differently
        // or just display an error message instead of your table using a <v-if> tag
        // or navigate to an error page
      }
    },
    formatDate(date) {
      return dateArrayToMoment(date).format('YYYY-MM-DD hh:mm');
    },
    customSort(items, index, isDesc) {
      items.sort((a, b) => {
        if (index[0] == 'startTime' || index[0] == 'endTime') {
          if (!isDesc[0]) {
            return (
              dateArrayToMoment(b[index]).toDate() -
              dateArrayToMoment(a[index]).toDate()
            );
          } else {
            return (
              dateArrayToMoment(a[index]).toDate() -
              dateArrayToMoment(b[index]).toDate()
            );
          }
        }
      });
      return items;
    }
  }
};
</script>

And here's the test spec that validates the component:

import Vue from 'vue'
import Vuetify from 'vuetify'
import ResultsList from '@/components/ResultsList'
import { mount, createLocalVue } from '@vue/test-utils'
import axios from 'axios'
import flushPromises from 'flush-promises';

Vue.use(Vuetify)

const localVue = createLocalVue()

var results = [
  {
    'id': 1,
    'state': 'COMPLETED',
    'startTime': [2020, 4, 21, 19, 42],
    'endTime': [2020, 4, 21, 19, 42],
    'type': 'Example Scheduled Task',
    'title': 'Example Scheduled Task at 2020-04-21 19:42:00',
    'resultMessage': 'Task finished successfully'
  },
  {
    'id': 2,
    'state': 'COMPLETED',
    'startTime': [2020, 4, 22, 13, 36],
    'endTime': [2020, 4, 22, 13, 36],
    'type': 'Example Scheduled Task',
    'title': 'Example Scheduled Task at 2020-04-22 13:36:00',
    'resultMessage': 'Task finished successfully'
  },
  {
    'id': 3,
    'state': 'COMPLETED',
    'startTime': [2020, 4, 22, 13, 37],
    'endTime': [2020, 4, 22, 13, 37],
    'type': 'Example Scheduled Task',
    'title': 'Example Scheduled Task at 2020-04-22 13:37:00',
    'resultMessage': 'Task finished successfully'
  }
];

// Mocking Axios with Jest
jest.mock('axios');

describe('ResultsList.vue', () => {
  let vuetify

  beforeEach(() => {
    vuetify = new Vuetify()

    axios.get.mockResolvedValue(results);
  })

  it('should have a custom title and match snapshot', async () => {
    const wrapper = mount(ResultsList, {
      localVue,
      vuetify,
      propsData: {
        title: 'Foobar',
      },
    })

    await flushPromises()

    // Snapshot generation with Jest
    expect(wrapper.html()).toMatchSnapshot()

  })
})

In the provided code, Axios is mocked out for testing purposes, and we utilize Jest to verify a snapshot. However, the issue arises as the snapshot doesn't display any data despite flushing promises before taking the snapshot.

Review the generated snapshot below, which shows an empty Data Table without any displayed data:

// Jest Snapshot v1

exports[`ResultsList.vue should match snapshot 1`] = `
<div class="container container--fluid" title="Foobar">
  <div class="v-card v-sheet theme--light">
    <div class="v-card__title">
      Results
      <div class="spacer"></div>
      // Additional components and elements follow..
    </div>
  </div>
</div>
`;

Answer №1

Here are a couple of suggestions to consider:

Ensure that you call wrapper.vm.$nextTick() before capturing the snapshot.

Instead of utilizing Vue.use(), experiment with localVue.use(Vuetify)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the method for invoking an imported function in a template?

Let's analyze the code snippet below, which utilizes a method and an imported function: <template> <div> {{sayHello()}} {{sayDate()}} {{DateTime.now()}} <div> </template> <script> import {DateTime} from & ...

Utilizing Vue router: a guide to sending data to the default route

Below is the configuration of my vue router: [ { name: 'home', path: '/', component: HomeComponent, props: true, }, { name: 'detail', path: '/detail/:id', ...

Perform time update every second

Is it feasible to have my timeupdate function run every second? (Using VUE CLI) @timeupdate="videoSecond" videoSecond(){ let Second = this.player.currentTime(); let CaptureList = this.capturesList; CaptureList.forEach(element => ...

Exploring the dynamics of Django, Webpack, and Vue with the added feature of code splitting: A guide to customizing chunk

I am currently using Django in conjunction with Webpack and Vue, as well as implementing Code splitting within Webpack. The issue I am facing is that Webpack splits chunk files from the source code of .vue files, but I am unable to load these chunk files i ...

Tips for refreshing a page in Vue.js

I am facing an issue with updating a table on my page after deleting a row. Each row in the table has a delete button and I have tried using window.location.reload() but it didn't work. </va-card> <br/> <va-card > ...

Leveraging Rails 5.1 with API integration, Webpacker, and Vue

I'm currently in the process of setting up a Rails API and VueJs client with webpacker on Cloud9. Following a standard installation: npm install -g yarn && rails _5.1.4_ new . --api --webpack=vue To launch both rails and webpack, I am using ...

Troubleshooting Nuxt 3 middleware redirect issue with IP country code on Netlify deployment

I am attempting to redirect traffic to a specific slug based on the user's country code following an IP address lookup. While this process works flawlessly on my local setup, I am encountering issues when deploying to Netlify. export default defineNu ...

Issue with closing Bootstrap 5 alert in Vue component

I'm currently tackling a Vue project and I'm stumped as to why this alert isn't closing. Initially, I had the commented-out section working fine, but when I replaced it with code from the Bootstrap website, the issue persisted. <template& ...

Switching the default port for a Vue.js application running in a Docker container

I am currently in the process of changing the default port for a Vue.js app running on docker. I have experimented with both examples provided in the official documentation, which can be found here. For instance, I have a Dockerfile using http-server: FR ...

What is the best way to invoke a method within the onSubmit function in Vuejs?

I am facing an issue with a button used to log in the user via onSubmit function when a form is filled out. I also need to call another method that will retrieve additional data about the user, such as privileges. However, I have been unsuccessful in makin ...

Jest's it.each method is throwing an error: "This expression is not callable. Type 'String' has no call signatures."

I've been attempting to utilize the describe.eachtable feature with TypeScript, but I keep running into an error message stating: "error TS2349: This expression is not callable. Type 'String' has no call signatures." Below is my code snippe ...

What could be causing my images not to show up when I use string interpolation for src links in Vue.js?

I've encountered an issue while working on Vue.js where I'm struggling to render a couple of images from the local directory. What puzzles me is that this problem arises when using string interpolation, like in the code snippet below: <img :s ...

Testing React Components - The `useClient` function should only be used within the `WagmiConfig` component

In my Next.js app with TypeScript, Jest, and React testing library, I encountered an error while trying to test a component. The error message states that `useClient` must be used within `WagmiConfig`. This issue arises because the `useAccount` hook relies ...

Importing Vue and Vuex modules from separate files

Recently, I encountered an uncommon issue. I decided to keep my main.js and store.js files separate in a Vue project. In the store.js file, I imported Vuex, set up a new vuex store, and exported it. However, when importing this file into main.js and settin ...

Encountering an Internal Server Error (500) when using Laravel8 with Vuex for POST requests

For the past 2 months, I have been immersing myself in Vue and Laravel. Recently, I embarked on a project to put my newfound knowledge into practice. While setting up several successful GET and POST routes, I encountered a persistent issue with one particu ...

Deciding on the optimal times to implement data structure methods within Vue.js applications

Currently studying the Vue.js v2 documentation and I'm noticing a difference in how data is structured. When looking at the official documentation, they demonstrate creating data like this: var data = { a: 1 } var vm = new Vue({ el: '#example&a ...

Error encountered in React when using Axios to send a POST request: Status code 400 received, indicating request failure

I'm currently working on a React project and facing an issue while trying to make a POST request to my Strapi backend API using Axios. The error message I am encountering is: { "message": "Request failed with status code 400", "name": "AxiosError" ...

Transmitting a Custom JS Object via Vue Router

Stuck! I’ve been hitting my head against the wall for hours trying to figure this out... Technologies Utilized: Vue (v3.0.0) Vue-Router (v4.0.0-0) Bootstrap (v5.1.1) The Objective: I have two pages (Home.vue, MetaUpdate.vue) and one component (Docum ...

Troubleshooting: Resolving the "maps" property reading issue in Quasar Vue Google Maps

Struggling to resolve the error "Cannot read property 'maps' of null" when trying to center the map using the following code snippet: const map = new this.google.maps.Map(document.getElementById('map'), { zoom: 13, c ...

The scrolling event on the div is not triggering

I'm struggling with this piece of code: const listElm = document.querySelector('#infinite-list'); listElm.addEventListener('scroll', e => { if(listElm.scrollTop + listElm.clientHeight >= listElm.scrollHeight) { th ...