Skip to content

Attempting to use vuex store fails with complaints about getters not being functions, even when they are #153

Closed
@unikitty37

Description

@unikitty37

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.4
  • Vue version: 2.6.11
  • node version: 14.5.0
  • yarn version: 1.22.4

Additional context

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions