Search code examples
javascriptunit-testingvue.jsvuex

How Test MapGetter


I would like to test if my getter is called in my component or view, but I don't understand how can it.

My method in the component :

computed: {
  ...mapGetters({ item: 'moduleA/getData' }),
},

And this is my unit test declaration :

beforeEach(() => {
    store = new Vuex.Store({
      modules: {
        moduleA: {
          state: {},
          getters: {
            getData() {
              return { item: { name: 'test' } };
            },
          },
        },
      },
    });
    wrapper = shallowMount(MyComponent, {
      store,
    });
  });

And I try to test if the data is loaded in my template:

it('should check if name is thruthy', () => {
  expect(wrapper.find('.classA').text()).toEqual('test');
});

my component :

<template>
  <v-content>
    <ComponentA v-if="item.name"
    key="keyA" ></ComponentA>
    <ComponentB v-else key="keyA"></ComponentB>
  </v-content>
</template>

<script>
import { mapGetters } from 'vuex';
import ComponentA from '@/components/ComponentA.vue';
import ComponentB from '@/components/ComponentB.vue';

export default {
  /**
   * Component's name :
   */
  name: 'ViewA',
  /**
   * Component's used :
   */
  components: {
    ComponentA,
    ComponentB,
  },
  /**
   * computed's used :
   */
  computed: {
    ...mapGetters({ item: 'moduleA/getData' }),
  },
};
</script>

and my getter in the moduleA :

const getters = {
  getData: state => state.data,
};

But I have this message:
TypeError: Cannot read property 'name' of undefined

Why? Thank you for your help.


Solution

  • As shown in docs, shallowMount's options has field named localVue. To solve your problem you should create a localVue, using createLocalVue and pass it to shallowMount.

    createLocalVue returns a Vue class for you to add components, mixins and install plugins without polluting the global Vue class.

    import Vuex from 'vuex'
    import { createLocalVue, shallowMount } from '@vue/test-utils'
    
    beforeEach(() => {
      const localVue = createLocalVue()
    
      localVue.use(Vuex)
    
      store = new Vuex.Store({
        modules: {
          moduleA: {
            state: {},
            getters: {
              getData() {
                return { item: { name: 'test' } }
              },
            },
          },
        },
      })
    
      wrapper = shallowMount(MyComponent, {
        localVue,
        store,
      })
    })