Unit testing 如何在使用vuex模块时测试突变

Unit testing 如何在使用vuex模块时测试突变,unit-testing,vue.js,vuex,vuex-modules,Unit Testing,Vue.js,Vuex,Vuex Modules,在使用vuex模块之前,我的突变测试还可以: import mutations from '@/vuex/mutations.js' import vueAuthInstance from '@/services/auth.js' import { IS_AUTHENTICATED, CURRENT_USER_ID } from '@/vuex/mutation_types.js' describe('mutations.js', () => { var state before

在使用vuex模块之前,我的突变测试还可以:

import mutations from '@/vuex/mutations.js'
import vueAuthInstance from '@/services/auth.js'
import { IS_AUTHENTICATED, CURRENT_USER_ID } from '@/vuex/mutation_types.js'

describe('mutations.js', () => {
  var state
  beforeEach(() => {
    state = {
      isAuthenticated: vueAuthInstance.isAuthenticated(),
      currentUserId: ''
    }
  })

  describe('IS_AUTHENTICATED', () => {
    it('should set authentication status', () => {
      state.isAuthenticated = false
      mutations[IS_AUTHENTICATED](state, {isAuthenticated: true})
      expect(state.isAuthenticated).to.eql(true)
    })
  })
  ...

})
现在我重构了vuex文件夹,我的状态和变化都在每个vuex/modules/./index.js文件中

      src
       |_  vuex
       |    L_ modules
       |           L_ login
       |               |_ index.js
       |               |_ actions.js
       |               |_ getters.js
       |               |_ mutation_types.js
       |_ App.vue
       |_ main.js
const mutations = {
  [types.IS_AUTHENTICATED]  (state, payload) {
    console.log('MUTATION state: ', state)
    console.log('MUTATION payload: ', payload)
    state.isAuthenticated = payload.isAuthenticated
  },
  [types.CURRENT_USER_ID]  (state, payload) {
    state.currentUserId = payload.currentUserId
  }
}
vuex/modules/login/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import actions from './actions'
import getters from './getters'
import * as types from './mutation_types'
import vueAuthInstance from '@/services/auth.js'
Vue.use(Vuex)

const state = {
  isAuthenticated: vueAuthInstance.isAuthenticated(),
  currentUserId: ''
}

const mutations = {
  [types.IS_AUTHENTICATED]  (state, payload) {
    state.isAuthenticated = payload.isAuthenticated
  },
  ...
}

export default {
  state,
  mutations,
  actions,
  getters
}
import { mutations } from '@/vuex/modules/login/index.js'
import vueAuthInstance from '@/services/auth.js'
import types from '@/vuex/modules/login/mutation_types.js'

describe('mutations.js', () => {
  var state
  beforeEach(() => {
    state = {
      isAuthenticated: vueAuthInstance.isAuthenticated(),
      currentUserId: ''
    }
  })

  describe('IS_AUTHENTICATED', () => {
    it('should set authentication status', () => {
      state.isAuthenticated = false
      mutations[types.IS_AUTHENTICATED](state, {isAuthenticated: true})
      expect(state.isAuthenticated).to.eql(true)
    })
  })

})
import store from '@/vuex/store'

describe('mutations.js', () => {
  describe('IS_AUTHENTICATED', () => {
    it('should set authentication status', () => {
      store.commit('IS_AUTHENTICATED', {isAuthenticated: true})
      expect(store.state.login.isAuthenticated).to.eql(true)
    })
  })
  ...
})
使用vuex/store.js

import Vue from 'vue'
import Vuex from 'vuex'
import login from '@/vuex/modules/login'
// import other modules

Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    login,
    ... (other modules )
  }
})
为了考虑这种新结构,我将单元测试重写如下:

test/unit/specs/vuex/modules/login/index.spec.js

import Vue from 'vue'
import Vuex from 'vuex'
import actions from './actions'
import getters from './getters'
import * as types from './mutation_types'
import vueAuthInstance from '@/services/auth.js'
Vue.use(Vuex)

const state = {
  isAuthenticated: vueAuthInstance.isAuthenticated(),
  currentUserId: ''
}

const mutations = {
  [types.IS_AUTHENTICATED]  (state, payload) {
    state.isAuthenticated = payload.isAuthenticated
  },
  ...
}

export default {
  state,
  mutations,
  actions,
  getters
}
import { mutations } from '@/vuex/modules/login/index.js'
import vueAuthInstance from '@/services/auth.js'
import types from '@/vuex/modules/login/mutation_types.js'

describe('mutations.js', () => {
  var state
  beforeEach(() => {
    state = {
      isAuthenticated: vueAuthInstance.isAuthenticated(),
      currentUserId: ''
    }
  })

  describe('IS_AUTHENTICATED', () => {
    it('should set authentication status', () => {
      state.isAuthenticated = false
      mutations[types.IS_AUTHENTICATED](state, {isAuthenticated: true})
      expect(state.isAuthenticated).to.eql(true)
    })
  })

})
import store from '@/vuex/store'

describe('mutations.js', () => {
  describe('IS_AUTHENTICATED', () => {
    it('should set authentication status', () => {
      store.commit('IS_AUTHENTICATED', {isAuthenticated: true})
      expect(store.state.login.isAuthenticated).to.eql(true)
    })
  })
  ...
})
我得到一个关于变异的错误:

 ✗ should set authentication status
    TypeError: Cannot read property 'IS_AUTHENTICATED' of undefined
我试图更改import{translations}语句,直接导入定义模块的store.js,并使用store

LOG: 'MUTATIONS: ', Object{IS_AUTHENTICATED: [function wrappedMutationHandler(payload) { ... }], ...}
正在使用store._.IS_AUTHENTICATED0,似乎可以工作,(不知道为什么是数组?),但由于测试未通过,此函数和状态payload args出现问题

import store from '@/vuex/store'
import vueAuthInstance from '@/services/auth.js'

describe('mutations.js', () => {
  var state
  beforeEach(() => {
    state = {
      isAuthenticated: vueAuthInstance.isAuthenticated(),
      currentUserId: ''
    }
  })

  describe('IS_AUTHENTICATED', () => {
    it('should set authentication status', () => {
      state.isAuthenticated = false
      console.log('MUTATIONS: ', store._mutations.IS_AUTHENTICATED())
      store._mutations.IS_AUTHENTICATED[0](state, {isAuthenticated: true})
      expect(state.isAuthenticated).to.eql(true)
    })
  })
  ...
})


1) should set authentication status
     mutations.js IS_AUTHENTICATED
     AssertionError: expected false to deeply equal true
我检查了index.js文件中传递给变异的参数

      src
       |_  vuex
       |    L_ modules
       |           L_ login
       |               |_ index.js
       |               |_ actions.js
       |               |_ getters.js
       |               |_ mutation_types.js
       |_ App.vue
       |_ main.js
const mutations = {
  [types.IS_AUTHENTICATED]  (state, payload) {
    console.log('MUTATION state: ', state)
    console.log('MUTATION payload: ', payload)
    state.isAuthenticated = payload.isAuthenticated
  },
  [types.CURRENT_USER_ID]  (state, payload) {
    state.currentUserId = payload.currentUserId
  }
}
和。我没有看到传递的arg值,状态args似乎是我测试中唯一传递的值:

LOG: 'MUTATION state: ', Object{isAuthenticated: false, currentUserId: ''}
LOG: 'MUTATION payload: ', Object{isAuthenticated: false, currentUserId: ''}
这个代码怎么了?在这种情况下,如何使用vuex模块继续测试突变


感谢您的反馈

我找到了一种使用vuex模块测试突变的方法,但我不知道这是否是最好的方法

我的测试非常简单,使用store.commit,因为我无法直接调用变异处理程序,并且只导入vuex/store

src/test/unit/specs/modules/login/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import actions from './actions'
import getters from './getters'
import * as types from './mutation_types'
import vueAuthInstance from '@/services/auth.js'
Vue.use(Vuex)

const state = {
  isAuthenticated: vueAuthInstance.isAuthenticated(),
  currentUserId: ''
}

const mutations = {
  [types.IS_AUTHENTICATED]  (state, payload) {
    state.isAuthenticated = payload.isAuthenticated
  },
  ...
}

export default {
  state,
  mutations,
  actions,
  getters
}
import { mutations } from '@/vuex/modules/login/index.js'
import vueAuthInstance from '@/services/auth.js'
import types from '@/vuex/modules/login/mutation_types.js'

describe('mutations.js', () => {
  var state
  beforeEach(() => {
    state = {
      isAuthenticated: vueAuthInstance.isAuthenticated(),
      currentUserId: ''
    }
  })

  describe('IS_AUTHENTICATED', () => {
    it('should set authentication status', () => {
      state.isAuthenticated = false
      mutations[types.IS_AUTHENTICATED](state, {isAuthenticated: true})
      expect(state.isAuthenticated).to.eql(true)
    })
  })

})
import store from '@/vuex/store'

describe('mutations.js', () => {
  describe('IS_AUTHENTICATED', () => {
    it('should set authentication status', () => {
      store.commit('IS_AUTHENTICATED', {isAuthenticated: true})
      expect(store.state.login.isAuthenticated).to.eql(true)
    })
  })
  ...
})

实际上,这是一个糟糕的方法。 您应该创建模拟状态,并使用它

import { createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';    
import { storeModule } from '@path/to/store/modules';
const mutations = storeModule.mutations;


describe('mutations', () => {
  it('testCase#1', () => {
    createLocalVue().use(Vuex);
    const state = {
    //mock state values
    };

    const store = new Vuex.Store({state, mutations});

    store.commit('mutationToTest', arg);

    expect(state.arg).toBe(1);
  })
})