DEV Community

Discussion on: Testing vue-apollo Components with Jest

Collapse
 
n_tepluhina profile image
Natalia Tepluhina

To be honest (and it's completely my personal preference) I prefer not to use Vue Apollo components. I know it's a valid way of doing things and it's a default for e.g. React; but I like my query logic separated from the template.

Perhaps I should try to test components with <ApolloQuery> and update an article though, thank you for the great question.

Collapse
 
tavo1987 profile image
Edwin Ramírez

Hi Natalia, If you do it would be very helpful and should also be in the documentation

Collapse
 
danroc profile image
Daniel da Rocha

Yeah, I am starting to think that the benefits do not compensate the issues with both testing and with Storybook.

I am on the verge of ditching them altogether. I find it also frustrating the lack of documentation about it; while at the same time that the vue-apollo docs express the wonders of using these components, they fail to mention how to test them.

Recently there was a recommendation to use <apollo-query> components with inline gql-formatted query, as "best practice". But it stopped there, and any component written this way seems to be untestable with current tools.

Thread Thread
 
tavo1987 profile image
Edwin Ramírez • Edited

Hi Daniel, I have the same problem, do you have any progress on this?

Thread Thread
 
danroc profile image
Daniel da Rocha

No, I just ditched the components alltogether.

I am also thinking of moving on from vue-apollo, especially when Vue3 comes around. Maybe try Villus?

Thread Thread
 
tavo1987 profile image
Edwin Ramírez • Edited

I haven't tried it yet but it looks like an interesting option.

I was able to test the component is rendered and receive the correct properties, what I can't achieve is mock the data that the component returns.

My tests look like this so far:

Hello.vue

<template>
    <ApolloQuery
            v-test="{ id: 'apollo-query' }"
            :query="require('@/graphql/MY_QUERY').default"
            :variables="{ id: 1 }"
            :notify-on-network-status-change="true"
          >
      <template v-slot="{ result: { loading, error, data } }">
        <div v-if="loading">
          Loading...
        </div>
        <div v-else-if="error">An error occurred</div>
        <div v-else-if="data">{{ data.hello }}</div>
        <div v-else>No result :(</div>
      </template>
    </ApolloQuery>
</template>

Hello.spec.js

import { mount, createLocalVue } from '@vue/test-utils'
import VueApollo from 'vue-apollo'
import Hello from '@/components/Hello'

const localVue = createLocalVue()
localVue.use(VueApollo)


describe('Hello.vue', () =>() {
    test('renders an ApolloQuery component', () =>{
        const wrapper = moun(Hello, {
            localvue,
            // To remove error in render: "TypeError: Cannot read property 'loading' of undefined"
            // More info about this https://github.com/vuejs/vue-apollo/issues/609 
            $apolloData: {
              loading: false
            },
        })

        // I'm using a custom directive v-test that transform this v-test="{id: 'foo'}" to [data-test-id=foo]
        const apolloQuery = wrapper.find('[data-test-id=apollo-query]')

        expect(apolloQuery.exists()).toBe(true)
        expect(apolloQuery.props().query).toBe(require('@/graphql/MY_QUERY').default)
        expect(apolloQuery.props().variables).toEqual({ id: 1 })
        expect(apolloQuery.props().notifyOnNetworkStatusChange).toBeTruthy()
    })
})