How can i write test for my component which is use Vuex with Typescript and Composition Api in Nuxt2 and Vue test util(VTU)?

Viewed 428

I have trouble with finding a good resource for writing tests for my component which is using Vuex with Typescript and Composition Api in Nuxt2, and how can I do this?

Here is my component codes:

<template>
  <div>
    <div data-test="open-sidebar" @click="openSidebar">
      Sidebar
      <hr>
      <div v-show="getSidebarStatus">Sidebar data</div>
    </div>
  </div>
</template>

<script lang="ts">
import { computed, defineComponent, useStore } from '@nuxtjs/composition-api'

export default defineComponent({
  name: 'Index',
  setup() {
    const store = useStore()
    const getSidebarStatus = computed((): any => {
      return store.getters.getSidebarStatus
    })
    const openSidebar = (): void => {
      store.dispatch('openSidebar')
    }
    return {
      getSidebarStatus,
      openSidebar,
    }
  },
})
</script>

And here is my Vuex module:

export const state = () => ({
  isSidebarOpen: false,
})

export const getters = {
  getSidebarStatus(state: any) {
    return state.isSidebarOpen
  },
}

export const mutations = {
  openSidebar: (state: any) => (state.isSidebarOpen = true),
}

export const actions = {
  openSidebar: (context: any) => context.commit('openSidebar'),
}
1 Answers

Finally, I found a solution for this issue:

First of all, install vuex if is not installed by default, Then, create a folder on your test/unit directory with everything you want, I named __mocks__, then a store.ts file, and put these codes on it:

import { state, getters, mutations, actions } from '~/store/index'

export default function storeConfig() {
  return {
    modules: {
      index: { state, getters, mutations, actions },
    },
  }
}

and then in your test file which for me is sidebar.spec.ts put these codes:

import { shallowMount, createLocalVue } from '@vue/test-utils'
import Vuex from 'vuex'
import Sidebar from '~/components/layouts/Sidebar/index.vue'
import storeConfig from '~/test/unit/__mocks__/store'

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

// eslint-disable-next-line import/no-named-as-default-member
const store = new Vuex.Store({
  state: storeConfig().modules.index.state,
  getters: storeConfig().modules.index.getters,
  mutations: storeConfig().modules.index.mutations,
  actions: storeConfig().modules.index.actions,
})

describe('layouts/Sidebar.vue', () => {
  test('checks if the sidebar is open', async () => {
    const wrapper = shallowMount(Sidebar, {
      store,
      localVue,
      stubs: {
        NuxtLink: true,
      },
    })
    const openSidebar = wrapper.find('[data-test="open-sidebar"]')

    await openSidebar.trigger('mouseover')

    expect(store.getters.getSidebarStatus).toBe(true)
  })
})

Important note : You should take store from useStore not useContext in the component

import {useStore} from '@nuxtjs/composition-api'
const store=useStore() // correct
-----------
import {useContext} from '@nuxtjs/composition-api'
const {store}=useContext() // incorrect
Related