用Jest对Vuetify数据表进行单元测试

时间:2020-04-28 15:56:38

标签: vue.js jestjs axios vuetify.js

我已经使用Vuetify创建了Vue.js应用程序,现在正尝试对包含Vuetify数据表的组件进行单元测试。数据表是使用Axios从后端REST API填充的,运行我的应用程序时可以正常工作,但是在我的单元测试中(我用Jest模拟了Axios),数据表从未填充

这是我的组件的来源

library(dplyr)
dat %>%
  group_by(grp1, grp2) %>%
  summarize(count = sum(count)) %>%
  ungroup() %>%
  mutate(freq = count / sum(count))
# # A tibble: 4 x 4
#    grp1  grp2 count   freq
#   <int> <int> <int>  <dbl>
# 1     1     3    22 0.0206
# 2     1     4   208 0.195 
# 3     2     3   383 0.358 
# 4     2     4   456 0.427 

这是测试组件的测试规范

<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>

如您所见,我使用Jest模拟Axios,以便它返回一些测试数据并使用Jest验证快照。

问题在于,尽管调用flushPromises来确保在拍摄快照之前已解决所有诺言,但快照不包含任何数据(测试或其他数据)。

这是快照。如您所见,数据表(测试或其他方式)中未显示任何数据。

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'
  }
];

// Use Jest to mock the Axios
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()

    // With jest we can create snapshot files of the HTML output
    expect(wrapper.html()).toMatchSnapshot()

  })
})

1 个答案:

答案 0 :(得分:1)

一些想法: 拍摄快照之前,请致电wrapper.vm.$nextTick()

请尝试使用Vue.use()

,而不要使用localVue.use(Vuetify)