如何在 VueJS test-utils parentComponent 中模拟 Vuex 商店

Posted

技术标签:

【中文标题】如何在 VueJS test-utils parentComponent 中模拟 Vuex 商店【英文标题】:How to mock a Vuex store in VueJS test-utils parentComponent 【发布时间】:2019-02-27 20:46:37 【问题描述】:

我正在使用Jestvue-test-utils 尝试测试子组件是否对父组件中的$emit 事件作出反应。

VueJS test-utils 库提供了一个parentComponent 选项,以便在安装/浅安装组件时传递。

除了我使用模拟的 Vuex 存储实例化组件之外,一切都运行良好,但父组件会抛出一个

TypeError:无法读取未定义的属性“状态”

在父组件中的 this.$store.state.something.here 代码段上。

如何在那里模拟 Vuex 商店?

组件挂载如下:

const wrapper = shallowMount(ChildComponent, 
  store,
  localVue,
  parentComponent: ParentComponent,
  mocks: 
    $t: msg => msg,
  ,
);

关于如何解决这个问题的任何想法?

【问题讨论】:

【参考方案1】:

这可能不是对 OP 问题的完整答案,但由于我在过去 2 小时内一直在调试并最终发现了我的问题,因此我想在此处发布以帮助将来的人。

我试图模拟和挂载以下组件:

<template>
<div test="object-list-div">
  <h1 test="component-title"> objectName </h1>
  <table class="table">
    <thead>
        <tr test="table-row-title">
            <th scope="col" test="table-column-title" v-for="(value, name, index) in objectData[0]" :key="index"> name </th>
        </tr>
    </thead>
    <tbody>
      <tr test="table-row-data" v-for="(ivalue, iname, i) in objectData" :key="i">
        <td test="table-cell-data" v-for="(jvalue, jname, j) in ivalue" :key="j"> jvalue </td>
      </tr>
    </tbody>
  </table>
</div>

export default  

    props: [
        'objectName',
        'objectData'
    ],
    computed: 
      visibleColums() 
        return this.$store.state.Config_ShowColumn;
      
    

使用以下包装代码

 wrapper = shallowMount(ObjectList, 
    mocks: 
      $store: 
        state: 
          Config_ShowColumn: [
            "Field1",
            "Field2",
            "Field3",
            "Field4",
            "Field5",
          ]
        
      
    
  );

我遇到了 OP 错误,但在我的情况下,组件 在创建时需要两个 Props。由于没有收到这个,所以卡住了。

现在正在运行:

import  shallowMount  from "@vue/test-utils";
import  expect  from "chai";
import ObjectList from "@/components/Object-List.vue";  

wrapper = shallowMount(ObjectList, 
    propsData: 
      objectName: "Ticket",
      objectData: [
        
          Field1: "Field1",
          Field2: "Field2",
          Field3: "Field3",
          Field4: "Field4",
          Field5: "Field5",
        ,
      ]
    , 
    mocks: 
      $store: 
        state: 
          Config_ShowColumn: [
            "Field1",
            "Field2",
            "Field3",
            "Field4",
            "Field5",
          ]
        
      
    
  );

希望对某人有所帮助。

【讨论】:

【参考方案2】:

尝试了 Richard 提出的解决方案,但没有取得多大成功,尽管他的猜测是正确的。

解决方案比我预想的要简单得多,我刚刚停止实例化 Vuex.Store,只是在 vue-test-utils config 中模拟了 $store,如下所示:

import  createLocalVue, shallowMount, config  from '@vue/test-utils';

config.mocks.$store = 
  state: 
    user: 
      sexy: true
    ,
  ,
;

我不需要使用 Vuex 的实际实例,因为我只需要模拟实际数据,所以这非常有效。

【讨论】:

确实,这也有效。见Vue unit testing - mocking imported services when using vue-test-utils mount。 Edd 说 >mocks 向 Vue 实例添加属性。【参考方案3】:

您是如何创建模拟商店的?它应该类似于

const storeOptions = 
  state: ...,
  getters: ...,
  mutations: ...

const mockStore = new Vuex.Store(storeOptions)

由于 this.$store 未定义,我怀疑您可能只是将选项对象传递给了 shallowMount。

【讨论】:

以上是关于如何在 VueJS test-utils parentComponent 中模拟 Vuex 商店的主要内容,如果未能解决你的问题,请参考以下文章

VueJs 如何删除全局错误处理程序以使用 vue-test-utils 进行测试

两个 shallowmount 抛出错误 Jest VueJs(Vuetify)

如何使用“@vue/test-utils”测试 VueRouter 的 beforeRouteEnter?

vue.js vuetify : test-utils w Jest 如何在使用图标时匹配文本

Vue test-utils 如何使用 vuetify 测试导航栏按钮

Vue 开发实战生态篇 # 25:单元测试的重要性及其使用