Overdrivr
Overdrivr

Reputation: 6596

Testing a getter that calls another getter, without mocking - or how to mount Vuex in tests?

I'm failing to understand something fundamental using Vuex: For a store that runs perfectly fine in the application, when running tests, due to dependency injection none of my getters that call other getters work.

See the following store that has two getters:

const state = {
  items: {},
}

const getters = {
  item: (state) => (itemIndex) => {
    return state.items[itemIndex]
  },
  reducedItem: (state, getters) => (itemIndex) => {
    return getters.item(itemIndex).reduce((acc, subitem) => {
        return acc + ';' + subitem.text
    }, '')
  }
}

const mutations = {
}

const actions = {
}

export default {
  state,
  getters,
  mutations,
  actions
}

And an example test:

import DemoStore from '@/store/modules/DemoStore'
import { expect } from 'chai'
const getters = DemoStore.getters

describe('store/DemoStore', () => {
  it('reducedItem reduces', () => {
    var state = {
      items: [
        [{text: 'a'}, {text: 'b'}, {text: 'c'}],
      ]
    }

    let result = getters.reducedItem(state, getters)(0)
    expect(result).to.equal('abc')
  })
})

When running the test, the reducedItem getter calls getters.item which instead of calling getters.item(state) and returning a proper value, calls the plain getters.item function, which returns a function. Therefore the code in testing environment is simply not working.

I understand Vuex recommends mocking getters but come on, it's not serious to consider mocking so deeply.

Is there a way to "mount" the vuex store in tests in order to use it exactly as in the application ?

Upvotes: 2

Views: 547

Answers (1)

Estus Flask
Estus Flask

Reputation: 222989

DemoStore is options object that is provided to Vuex constructor. Vuex can be created like:

let store = new Vuex.Store(DemoStore);

Getters are supposed to be available as store.getters and behave like it's expected from Vuex store.

Upvotes: 1

Related Questions