Reputation: 101
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
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
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
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