1.0.0-beta.10
http://jsfiddle.net/m33w0o9p/2/
For jest testing with vuex, if vuex contains both namespaced modules and global actions or states, it doesn't work. It will produce Cannot read property 'getters' of undefined error.
Testing file
import { shallow, createLocalVue } from '@vue/test-utils'
import Vuex from 'vuex'
import App from '@/App'
import auth from '../../../src/store/module/auth'
const localVue = createLocalVue()
localVue.use(Vuex)
describe('App', () => {
let actions
let store
beforeEach(() => {
actions = {
toggleDevice: jest.fn()
}
store = new Vuex.Store({
state: {},
modules: {
auth
},
actions
})
})
it('should have beforeMount hook', () => {
const wrapper = shallow(App, { store, localVue })
wrapper.setComputed({tokenExpired: true})
})
})
App.vue
export default {
name: 'app',
beforeMount () {
this.toggleDevice()
},
mounted () {
this.loadAuth()
},
computed: {
...mapGetters({
tokenExpired: 'auth/tokenExpired'
})
},
watch: {
tokenExpired () {
if (this.tokenExpired) {
this.$router.push('/login')
}
}
},
methods: mapActions({
toggleDevice: 'toggleDevice',
loadAuth: 'auth/loadAuth'
})
}
module/auth.js
const state = () => {
return {
tokenExpired: false
}
}
const getters = {
tokenExpired: state => state.tokenExpired
}
To pass the test
It doesn't compile, just suggesting Cannot read property 'getters' of undefined
I tried to make vuex store exactly like the one in production, it doesn't work.
I tried to combine the getters from the module to the global getters, it doesn't work either.
So I believe it is a bug
Thanks for the bug report 🙂
I tried to create a minimal reproduction with your code, but there were parts I had to guess. I can't reproduce this error using a namespaced module and mapGetters.
Can you create a full reproduction using this JSFiddle as a starting point—https://jsfiddle.net/eddyerburgh/2mzsL00d/4/
Here: https://jsfiddle.net/L5fye9w0/1/
run it and open up the console, you will see the error message
You need to pass the store instance—https://jsfiddle.net/eddyerburgh/sghur81m/1/
Sorry, my bad, I use vue-jest and jest, and I can't figure a way out to use them on jsfiddle: https://jsfiddle.net/L5fye9w0/4/
my actual testing code look like this
const localVue = createLocalVue()
localVue.use(Vuex)
describe('App', () => {
let actions
let store
beforeEach(() => {
actions = {
toggleDevice: jest.fn()
}
store = new Vuex.Store({
state: {},
modules: {
auth
},
actions
})
})
it('should have beforeMount hook', () => {
const wrapper = shallow(App, { store, localVue })
wrapper.setComputed({tokenExpired: true})
})
})
I figured out what the problem is, I passed in the fake store with a real module, but in this real module, it calls another getter from the real store, but since I don't have this getter method in the fake store, it gives me the error
I figured out what the problem is, I passed in the fake store with a real module, but in this real module, it calls another getter from the real store, but since I don't have this getter method in the fake store, it gives me the error
@WangHansen I have the same exact issue, what did you do to bypass this?
@bennettdams You need to provide getters to your test store if you want your component to be able to access their data. You can mock them with jest if you are testing whether or not they are called.
const localVue = createLocalVue()
localVue.use(Vuex)
describe('App', () => {
let actions
let store
beforeEach(() => {
actions = {
toggleDevice: jest.fn()
}
store = new Vuex.Store({
modules: {
auth: {
state: {},
getters: {
myFunc: jest.fn()
}
},
actions
})
})
it('should have beforeMount hook', () => {
const wrapper = shallow(App, { store, localVue })
wrapper.setComputed({tokenExpired: true})
})
})
Alternatively, if you export your getters from your auth module file, you can import that directly into your test and use all of the logic.
import { getters } from '../somepath/modules/auth'
const localVue = createLocalVue()
localVue.use(Vuex)
describe('App', () => {
let actions
let store
beforeEach(() => {
actions = {
toggleDevice: jest.fn()
}
store = new Vuex.Store({
modules: {
auth: {
state: {},
getters
},
actions
})
})
it('should have beforeMount hook', () => {
const wrapper = shallow(App, { store, localVue })
wrapper.setComputed({tokenExpired: true})
})
})
Be sure to provide all of the initial values to your auth state so your getters are not looking for undefined values :)
Just my two cents. I think whats happening here is Test case is trying to create actual store. Obviously creation of Store will have modules and getters defined. It will use store we have defined in our code. In test case I had to explicitly import store and getters
Most helpful comment
I figured out what the problem is, I passed in the fake store with a real module, but in this real module, it calls another getter from the real store, but since I don't have this getter method in the fake store, it gives me the error