Как захватить реквизит объекта в тестах моментальных снимков Vue

#unit-testing #vue.js #jestjs #vue-test-utils

#модульное тестирование #vue.js #jestjs #vue-test-utils

Вопрос:

Я всегда получаю [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>
  

Ответ №1:

Вы могли бы использовать пользовательский сериализатор моментальных снимков шутки.

Для VueJS 2 вы могли бы использовать https://github.com/tjw-lint/jest-serializer-vue-tjw — но это не работает для VueJS 3 (https://github.com/tjw-lint/jest-serializer-vue-tjw/pull/64).

Пример конфигурации для VueJS 2:

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

Комментарии:

1. Я надеюсь, что теперь это более понятно