首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Jest对验证数据表进行单元测试

使用Jest对验证数据表进行单元测试
EN

Stack Overflow用户
提问于 2020-04-28 23:56:39
回答 1查看 2.4K关注 0票数 0

我已经使用Vuetify创建了一个Vue.js应用程序,现在正在尝试对一个包含Vuetify Data Table的组件进行单元测试。数据表是使用Axios从后端REST API填充的,当我运行应用程序时,它工作得很好,但是在我的单元测试(我用Jest模拟Axios )中,数据表永远不会填充

下面是我的组件的源代码

代码语言:javascript
复制
<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>

下面是测试组件的测试规范

代码语言:javascript
复制
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()

  })
})

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

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

这是快照。如您所见,数据表中没有显示任何数据,无论是测试还是其他。

代码语言:javascript
复制
// 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>
      <div class="v-input v-input--hide-details theme--light v-text-field v-text-field--single-line">
        <div class="v-input__control">
          <div class="v-input__slot">
            <div class="v-text-field__slot"><label for="input-4" class="v-label theme--light" style="left: 0px; position: absolute;">Search</label><input id="input-4" type="text"></div>
            <div class="v-input__append-inner">
              <div class="v-input__icon v-input__icon--append"><i aria-hidden="true" class="v-icon notranslate mdi mdi-magnify theme--light"></i></div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="v-data-table theme--light">
      <div class="v-data-table__wrapper">
        <table>
          <colgroup>
            <col class="">
            <col class="">
            <col class="">
            <col class="">
            <col class="">
          </colgroup>
          <thead class="v-data-table-header">
            <tr>
              <th role="columnheader" scope="col" aria-label="Task" class="text-start"><span>Task</span></th>
              <th role="columnheader" scope="col" aria-label="State: Not sorted. Activate to sort ascending." aria-sort="none" class="text-start sortable"><span>State</span><i aria-hidden="true" class="v-icon notranslate v-data-table-header__icon mdi mdi-arrow-up theme--light" style="font-size: 18px;"></i></th>
              <th role="columnheader" scope="col" aria-label="Start Time: Not sorted. Activate to sort ascending." aria-sort="none" class="text-start sortable"><span>Start Time</span><i aria-hidden="true" class="v-icon notranslate v-data-table-header__icon mdi mdi-arrow-up theme--light" style="font-size: 18px;"></i></th>
              <th role="columnheader" scope="col" aria-label="End Time: Not sorted. Activate to sort ascending." aria-sort="none" class="text-start sortable"><span>End Time</span><i aria-hidden="true" class="v-icon notranslate v-data-table-header__icon mdi mdi-arrow-up theme--light" style="font-size: 18px;"></i></th>
              <th role="columnheader" scope="col" aria-label="Result: Not sorted. Activate to sort ascending." aria-sort="none" class="text-start sortable"><span>Result</span><i aria-hidden="true" class="v-icon notranslate v-data-table-header__icon mdi mdi-arrow-up theme--light" style="font-size: 18px;"></i></th>
            </tr>
          </thead>
          <tbody>
            <tr class="v-data-table__empty-wrapper">
              <td colspan="5">No data available</td>
            </tr>
          </tbody>
        </table>
      </div>
      <div class="v-data-footer">
        <div class="v-data-footer__select">Rows per page:<div class="v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-select">
            <div class="v-input__control">
              <div role="button" aria-haspopup="listbox" aria-expanded="false" aria-owns="list-17" class="v-input__slot">
                <div class="v-select__slot">
                  <div class="v-select__selections">
                    <div class="v-select__selection v-select__selection--comma">10</div><input aria-label="$vuetify.dataTable.itemsPerPageText" id="input-17" readonly="readonly" type="text" aria-readonly="false" autocomplete="off">
                  </div>
                  <div class="v-input__append-inner">
                    <div class="v-input__icon v-input__icon--append"><i aria-hidden="true" class="v-icon notranslate mdi mdi-menu-down theme--light"></i></div>
                  </div><input type="hidden" value="10">
                </div>
                <div class="v-menu">
                  <!---->
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="v-data-footer__pagination">–</div>
        <div class="v-data-footer__icons-before"><button type="button" disabled="disabled" class="v-btn v-btn--disabled v-btn--flat v-btn--icon v-btn--round v-btn--text theme--light v-size--default" aria-label="Previous page"><span class="v-btn__content"><i aria-hidden="true" class="v-icon notranslate mdi mdi-chevron-left theme--light"></i></span></button></div>
        <div class="v-data-footer__icons-after"><button type="button" disabled="disabled" class="v-btn v-btn--disabled v-btn--flat v-btn--icon v-btn--round v-btn--text theme--light v-size--default" aria-label="Next page"><span class="v-btn__content"><i aria-hidden="true" class="v-icon notranslate mdi mdi-chevron-right theme--light"></i></span></button></div>
      </div>
    </div>
  </div>
</div>
`;
EN

回答 1

Stack Overflow用户

发布于 2020-04-29 05:07:59

一些想法:在拍摄快照之前调用wrapper.vm.$nextTick()

尝试使用localVue.use(Vuetify)而不是Vue.use()

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61484502

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档