Testing VueJS fetch() using Apollo and Nuxt

Viewed 144

I am trying to test the async fetch() function of my Vue Component. This method uses some of the props to build a query to use with our Apollo GQL instance. I'm having a hard time finding examples using a similar configuration that I am using.

Ultimately, I'd love to test the full query (building it and the return data) but if it is difficult to test the full return data, then I can settle with just testing the building process of the variables and hopefully the schema of the return data.

// ProductList.spec.js
import { shallowMount } from '@vue/test-utils'
import ProductListing from '~/components/blocks/ProductListing.vue'
import PRODUCT_LISTING_BLOCK_QUERY from '~/queries/productListingBlock.gql'

import '@testing-library/jest-dom'

const directives = {
  interpolation: () => {}
}

const mocks = {
  $md: {
    render: value => value
  }
}

describe('ProductListing', () => {
  test('fetch from apollo', () => {    
  const testVariables = {
      maxItems: 10,
      matchSkus: 'ms239,mk332,as484',
      matchTags: 'tag1,tag2,tag3',
      matchCategories: '111,222,333,444'
    }
    const wrapper = shallowMount(ProductListing, {
      propsData: testVariables,
      stubs: ['ProductTileList'],
      directives,
      mocks
    })

    const client = this.$apollo.provider.clients.defaultClient // get an error on this line saying $apollo is undefined
    const products = await client
      .query({
        PRODUCT_LISTING_BLOCK_QUERY,
        testVariables,
        context: {
          clientName: 'powerchord'
        }
      })
      .then(r => r.data.allProducts)

    // const promise = wrapper.vm.fetch() // this doesn't seem to work/call my function
  })
})

// ProductList.vue
<template lang="pug">
.mb-8(:id='elementId')
  ProductTileList(:products="products")
</template>
<script lang="ts">
import Vue from 'vue'
import BaseBlockMixin from './BaseBlockMixin'
import query from '~/queries/productListingBlock.gql'
import { IObjectKeys } from '~/types/common-types'

import mixins from '~/utils/typed-mixins'

const Block = Vue.extend({
  props: {
    matchCategories: {
      type: String,
      default: ''
    },
    matchSkus: {
      type: String,
      default: ''
    },
    matchTags: {
      type: String,
      default: ''
    },
    maxItems: {
      type: Number,
      default: 20
    }
  },
  data () {
    return {
      products: []
    }
  },
  async fetch () {
    const client = this.$apollo.provider.clients.defaultClient

    const variables: IObjectKeys = {
      limit: this.maxItems
    }

    if (this.matchSkus.length) {
      variables.skus = this.matchSkus.split(',')
    }

    if (this.matchTags.length) {
      variables.tags = this.matchTags.split(',')
    }

    if (this.matchCategories.length) {
      variables.categories = this.matchCategories.split(',')
        .map(c => parseInt(c))
        .filter(c => !isNaN(c))
    }

    this.products = await client
      .query({
        query,
        variables,
        context: {
          clientName: 'some-company'
        }
      })
      .then((r: any) => r.data.allProducts)
  }
})
export default mixins(Block).extend(BaseBlockMixin)
</script>
0 Answers
Related