André Ramos
André Ramos

Reputation: 101

How to mock a Vuex store in VueJS test-utils parentComponent

I'm using Jest with vue-test-utils trying to test if a child component reacts to an $emit event in the parent component.

VueJS test-utils library provides a parentComponent option to be passed when mounting/shallow mounting the component.

Everything is working fine except that even though I instantiate the component with a mocked Vuex store, the parent component throws a

TypeError: Cannot read property 'state' of undefined

on a this.$store.state.something.here piece of code in the parent component.

How can I mock the Vuex store there?

The component mount looks like this:

const wrapper = shallowMount(ChildComponent, {
  store,
  localVue,
  parentComponent: ParentComponent,
  mocks: {
    $t: msg => msg,
  },
});

Any ideas on how to solve this?

Upvotes: 3

Views: 8750

Answers (3)

Christian
Christian

Reputation: 312

it may not be the complete answer to OP questions, but since I had been debugging around for the last 2h and finally found MY problem, I would like to posted here to help someone in the future.

I was trying to mock and mount the following component:

<template>
<div test="object-list-div">
  <h1 test="component-title">{{ objectName }}</h1>
  <table class="table">
    <thead>
        <tr test="table-row-title">
            <th scope="col" test="table-column-title" v-for="(value, name, index) in objectData[0]" :key="index">{{ name }}</th>
        </tr>
    </thead>
    <tbody>
      <tr test="table-row-data" v-for="(ivalue, iname, i) in objectData" :key="i">
        <td test="table-cell-data" v-for="(jvalue, jname, j) in ivalue" :key="j">{{ jvalue }}</td>
      </tr>
    </tbody>
  </table>
</div>

export default  {

    props: [
        'objectName',
        'objectData'
    ],
    computed: {
      visibleColums() {
        return this.$store.state.Config_ShowColumn;
      }
    }
}

with the following wrapper code

 wrapper = shallowMount(ObjectList, {
    mocks: {
      $store: {
        state: {
          Config_ShowColumn: [
            "Field1",
            "Field2",
            "Field3",
            "Field4",
            "Field5",
          ]
        }
      }
    }
  });

I got OP error, but in my case the component was expecting two Props at the moment of creation. Since it did not receive this, it got stuck.

This is working now:

import { shallowMount } from "@vue/test-utils";
import { expect } from "chai";
import ObjectList from "@/components/Object-List.vue";  

wrapper = shallowMount(ObjectList, {
    propsData: {
      objectName: "Ticket",
      objectData: [
        {
          Field1: "Field1",
          Field2: "Field2",
          Field3: "Field3",
          Field4: "Field4",
          Field5: "Field5",
        },
      ]
    }, 
    mocks: {
      $store: {
        state: {
          Config_ShowColumn: [
            "Field1",
            "Field2",
            "Field3",
            "Field4",
            "Field5",
          ]
        }
      }
    }
  });

Hope it helps someone.

Upvotes: 5

Andr&#233; Ramos
Andr&#233; Ramos

Reputation: 101

Tried the solution Richard proposed but without much success, even though his guess was right.

The solution was far simnpler than I envisioned, I just stopped instantiating the Vuex.Store and just have the mocked $store in vue-test-utils config like so:

import { createLocalVue, shallowMount, config } from '@vue/test-utils';

config.mocks.$store = {
  state: {
    user: {
      sexy: true
    },
  },
};

I had no need to use an actual instance of Vuex as I only needed to mock the actual data so this worked perfectly.

Upvotes: 3

Richard Matsen
Richard Matsen

Reputation: 23463

How are you creating the mock store? It should be something like

const storeOptions = {
  state: {...},
  getters: {...},
  mutations: {...}
}
const mockStore = new Vuex.Store(storeOptions)

Since this.$store is undefined, I suspect you might just be passing the options object to shallowMount.

Upvotes: 2

Related Questions