Vue 测试工具。 .vue 文件中使用了模拟 vuex,但 .ts 文件中使用了原始 vuex
Posted
技术标签:
【中文标题】Vue 测试工具。 .vue 文件中使用了模拟 vuex,但 .ts 文件中使用了原始 vuex【英文标题】:vue-test-utils. Mocked vuex is used in .vue file, but original vuex is used in .ts file 【发布时间】:2021-09-28 17:40:36 【问题描述】:我正在使用 vue-test-utils 测试我的 vue 项目。
因为我的项目使用了vuex store,所以我在测试文件中mock了vuex。
问题似乎是 .vue 文件调用模拟存储而 .ts 文件调用原始存储。
这是我的代码。
transfers.test.js
...
const localVue = createLocalVue()
localVue.use(ElementUI)
localVue.use(Vuex)
localVue.component('DefaultLayout', DefaultLayout)
const store = new Vuex.Store( // Mocked store
state:
transferDetailModal: false,
...
,
mutations:
showTransferDetailModal (state, detailPayload) // It makes 'transferDetailModal' true
console.log('run2')
state.clickedTransferDetailId = detailPayload.transferId
...
const wrapper = mount(Transfers, // Mount component using mock store
localVue,
store,
mocks:
...
describe('TransferDetailModal', () =>
test('open and close', async () =>
expect(wrapper.find('.transfer_id_column button').exists()).toBe(true)
wrapper.find('.transfer_id_column button').trigger('click') // It calls mutation.
await nextTick()
console.log(wrapper.vm.getTransferDetailModal)
// It logs getter of 'transferDetailModal', and false.
)
TransferState.ts(vuex store的模块)
...
export const transfersStore: Module<TransfersState, RootState> = // Original vuex store
state:
...
,
mutations:
showTransferDetailModal (state, detailPayload: transferId: string, remittanceList: Array<Remittance> )
console.log('run1')
state.clickedTransferDetailId = detailPayload.transferId
...
Transfers.vue
...
export default class Transfers extends Vue
@Getter getTextObjectStatus: any
@Getter getTransferDetailModal: any // @Getter is the expression of vue-property-decorator
...
TransfersPresentation.ts
...
callback: () =>
store.commit('showTransferDetailModal', transferId: remittance.id, remittanceList: this.remittanceList ) // It makes transferDetailModal true
console.log(store.getters.getTransferDetailModal) // It logs true
...
过程是
在测试中点击 wrapper.find('.transfer_id_column button') 时调用 TransferPresentation 的回调。
在回调中提交使“transferDetailModal”为真。但是'run1'被记录了,这意味着原始vuex存储的突变被称为不是模拟存储的那个。
TransferPresentation 中的console.log(store.getters.getTransferDetailModal) 也将其记录为 true。意思是原始store的getter是get。
但是,测试文件中的 console.log(wrapper.vm.getTransferDetailModal) 仍然将其记录为 false。这意味着它仍然会得到一个 mocked Store 的 getter。 (当我将模拟商店的值更改为 true 进行测试时,它会记录为 true)
那么我怎样才能让 TransferPresentation(.ts 文件)中的 getter 和 commit 也引用模拟存储,而不是原始存储?
【问题讨论】:
【参考方案1】:我只是通过不模拟 vuex 存储,而是使用下面的原始存储解决了这个问题。
index.ts
Vue.use(Vuex)
...
const store: StoreOptions<RootState> =
state:
...
,
mutations:
...
,
actions: ,
modules:
...
,
getters:
export default new Vuex.Store<RootState>(store)
transfers.test.js
...
import indexStore from '../../store/index'
...
const localVue = createLocalVue()
...
localVue.use(Vuex)
...
const store = indexStore
describe('With params: all', () =>
...
const wrapper = mount(Transfers,
localVue,
store,
...
【讨论】:
【参考方案2】:更准确地说,您不是在模拟商店,您使用的是真实商店,而是您在测试文件中创建的商店。
如果你想mock
你应该删除你的store
对象,并在调用mock
属性时将所有Vuex store
逻辑包含在mount
中,例如:
const wrapper = mount(Transfers,
mocks:
$store:
getters:
// your getters
,
actions:
// your actions
,
);
如果您想继续测试您已经开始的方式,问题可能实际上是您在安装组件之前没有调用localVue.use(Vuex)
,至少您没有在提供的代码中显示该行。
【讨论】:
以上是关于Vue 测试工具。 .vue 文件中使用了模拟 vuex,但 .ts 文件中使用了原始 vuex的主要内容,如果未能解决你的问题,请参考以下文章
在 vue-multiselect 中测试 vuex 操作时调用了 Jest 预期的模拟函数
在 Vue 3 的 Jest 测试中模拟 vue-router 的 useRoute()