首页 > 解决方案 > 如何在 Vue 快照测试中捕获对象道具

问题描述

当我使用快照测试时,由于对象到字符串的强制,我总是[object Object]代替对象道具。我该如何解决?我尝试将元素包装到JSON.stringify()中,但它会导致"Converting circular structure to JSON"错误。

生成的快照示例:

exports[`SalesList.vue Снапшот десктоп 1`] = `
<magic-grid-stub
  class="sales-list"
  cols="[object Object]"
  gaps="[object Object]"
  usemin="true"
>
  <sales-item-stub
    class="item"
    sale="[object Object]"
  />
  <sales-item-stub
    class="item"
    sale="[object Object]"
  />
  <sales-item-stub
    class="item"
    sale="[object Object]"
  />
  <sales-item-stub
    class="item"
    sale="[object Object]"
  />
   
  <sales-info-stub
    class="item"
    content="additionalInfo"
  />
</magic-grid-stub>
`;

我有简单的相应快照测试,比如这个:

import { createLocalVue, shallowMount } from '@vue/test-utils'
import SalesList from '@/components/sales/SalesList.vue'

let localVue

const fakeSale = {
  code: 'code',
  description: 'description',
  title: 'title',
  image: 'image',
  archive: false,
  visible: true,
  date_to: '2020/08/01',
  short_description: 'short_description',
  slug: 'slug',
  date_from: '2020/06/01',
  seo: {
    seo_description: 'seo_description',
    seo_title: 'seo_title',
    seo_keywords: 'seo_keywords',
  },
}

function createWrapper(component, options) {
  return shallowMount(component, {
    localVue,
    ...options,
  })
}

beforeAll(() => {
  localVue = createLocalVue()
})

describe('SalesList.vue', () => {
  it('Снапшот десктоп', async () => {
    expect.assertions(1)
    const wrapper = createWrapper(SalesList, {
      propsData: {
        sales: Array.from({ length: 4 }, (_, index) => ({
          ...fakeSale,
          slug: `slug-${index}`,
        })),
        additionalInfo: 'additionalInfo',
      },
      mocks: {
        $device: { isDesktop: true },
      },
    })
    expect(wrapper.element).toMatchSnapshot()
  })
})

以及相关组件本身:

<script lang="ts">
import SalesItem from '@/components/sales/SalesItem.vue'
import MagicGrid from '@/components/MagicGrid.vue'
import SalesInfo from '@/components/sales/SalesInfo.vue'
import Vue from 'vue'

export default Vue.extend({
  name: 'SalesList',
  components: {
    SalesItem,
    MagicGrid,
    SalesInfo,
  },
  props: {
    sales: {
      type: Array,
      required: true,
    },
    additionalInfo: {
      type: String,
      default: null,
    },
  },
  computed: {
    colsAndGaps(): {
      cols: { 0: number }
      gaps: { 0: number }
    } {
      return this.$device.isDesktopOrTablet
        ? {
          cols: {0: 2},
          gaps: {0: 30},
        }
        : {
          cols: {0: 1},
          gaps: {0: 16},
        }
    },
  },
})
</script>

<template>
  <magic-grid v-bind="colsAndGaps" class="sales-list">
    <sales-item
      v-for="sale in sales"
      :key="sale.slug"
      :sale="sale"
      class="item"
    />
    <sales-info v-if="additionalInfo" :content="additionalInfo" class="item"/>
  </magic-grid>
</template>

标签: unit-testingvue.jsjestjsvue-test-utils

解决方案


您可以使用自定义开玩笑快照序列化程序

对于 VueJs 2,您可以使用https://github.com/tjw-lint/jest-serializer-vue-tjw - 但它不适用于 VueJs 3 ( https://github.com/tjw-lint/jest-序列化程序-vue-tjw/pull/64)。

VueJs 2 的示例配置:

npm install jest-serializer-vue-tjw
// package.json
{
  ...
  "jest": {
    "snapshotSerializers": ["jest-serializer-vue-tjw"]
   }
}

推荐阅读