Description
Describe the bug A clear and concise description of what the bug is.
Attempting to use the vuex store in a test produces the error [vuex] getters should be function but "getters.user/isAnonymous" is true.
when getters are defined on the store. The test itself is marked as failed without being executed.
The same component renders under vue-cli-service serve
, with all behaviour as expected and no console errors.
isAnonymous
is not called in any code path called by the test. If the getters are reordered, the error message will complain about whichever one is first.
There's nothing in the vuex example that covers this, and I seem to be doing the same stuff as in that example. Of course, that's the only example I can find for vuex, and it doesn't define any getters, so I can't tell if I've done something wrong or if this is a bug.
To Reproduce Steps to reproduce the behaviour:
Given a vue-cli project with the following test in tests/unit/components/helpers/test-component.spec.js
:
import { render } from '@testing-library/vue'
import store from '@/store'
import testComponent from '@/components/test-component'
const renderComponent = (customStore) => render(testComponent, {
store: { ...store, ...customStore },
})
describe('test-component.vue', () => {
describe('when a user is logged out', () => {
it('tells them their user level is insufficient', () => {
const { container } = renderComponent({
state: {
user: {
id: null,
username: null,
userLevel: 'anonymous',
},
},
})
expect(container).toHaveTextContent('You need to log in to see this content.')
})
})
})
with the following in src/store/index.js
:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import user from './user.js'
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
},
modules: {
user,
},
})
and the following in src/store/user.js
:
const userLevels = {
'anonymous': 0,
'viewer': 1,
'editor': 2,
'admin': 3,
}
import { nullUser } from '@/objects/null-user'
const state = {
...nullUser,
}
const getters = {
isAnonymous: (state) => userLevel(state.userLevel) === userLevels.anonymous,
isViewer: (state) => userLevel(state.userLevel) === userLevels.viewer,
isEditor: (state) => userLevel(state.userLevel) === userLevels.editor,
isAdmin: (state) => userLevel(state.userLevel) === userLevels.admin,
}
const actions = {
logIn ({ commit }, payload) {
commit('LOG_IN', payload)
},
logOut ({ commit }) {
commit('LOG_OUT')
},
}
const mutations = {
LOG_IN (state, payload) {
state.id = payload.user.id
state.username = payload.user.username
state.userLevel = payload.user.userLevel
},
LOG_OUT (state) {
state.id = nullUser.id
state.username = nullUser.username
state.userLevel = nullUser.userLevel
},
}
export default {
namespaced: true,
state,
getters,
actions,
mutations,
}
then the test should run.
(The component under test merely renders one message if the store's user.id
is null or undefined, and a different message otherwise; I've omitted it to save space.)
Expected behaviour
The test runs, and either passes or fails depending on whether the component is correctly written. But the component is actually rendered.
Related information:
@testing-library/vue
version: 5.0.4Vue
version: 2.6.11node
version: 14.5.0yarn
version: 1.22.4
Additional context