如何解决 vuex 和单元测试的问题?

Posted

技术标签:

【中文标题】如何解决 vuex 和单元测试的问题?【英文标题】:How can I solve problem with vuex and unit-testing? 【发布时间】:2020-02-16 21:08:10 【问题描述】:

我第一次尝试使用 mocha 编写和运行单元测试,但遇到了一些问题。 我有一个组件 Table.vue 用 vuetify 写的

    <v-container>
        <h1>Table</h1>
        <v-layout
                text-center
                wrap
        >
            <v-simple-table v-if="table.length">
                <template v-slot:default>
                    <thead>
                    <tr>
                        <th class="text-left">Id</th>
                        <th class="text-left">Name</th>
                        <th class="text-left">Description</th>
                        <th class="text-left">Action</th>
                    </tr>
                    </thead>
                    <tbody>
                    <tr v-for="(item, index) in table" :key="index">
                        <td> item.id </td>
                        <td> item.name </td>
                        <td> item.description </td>
                        <td>
                            <v-btn
                                    color="blue"
                                    :to="name: 'create', params:  item: item, id: item.id "
                            >
                                Update
                            </v-btn>
                            <v-btn
                                    color="red"
                                    @click="show(item)"
                            >
                                Delete
                            </v-btn>
                        </td>
                    </tr>
                    </tbody>
                </template>
            </v-simple-table>
        </v-layout>
        <v-btn
                :to="name: 'create'"
                color="primary"
        >
            <span class="mr-2">Create</span>
        </v-btn>
        <modal name="hello-world">
            <v-container>
                <v-layout
                        text-center
                        wrap
                >
                    Are you sure you eant to remove this item?
                </v-layout>
                <v-layout
                        text-center
                        wrap
                >
                    <v-btn
                            color="red"
                            @click="deleteItem"
                    >
                        Yes
                    </v-btn>
                    <v-btn
                            color="primary"
                            @click="hide"
                    >
                        No
                    </v-btn>
                </v-layout>
            </v-container>
        </modal>
    </v-container>
</template>

<script>
    import  mapState, mapActions  from 'vuex'
    export default 
        name: "Table",
        data() 
            return 
                itemToRemove: null
            
        ,
        methods: 
            ...mapActions([
                'removeItem'
            ]),
            show (item) 
                this.$modal.show('hello-world');
                this.itemToRemove = item
            ,
            hide () 
                this.$modal.hide('hello-world');
                this.itemToRemove = null
            ,
            deleteItem () 
                this.removeItem(this.itemToRemove)
                this.hide()
            
        ,
        computed:
            mapState(
            table: state => state.table.table
        )
    
</script>

<style scoped>

</style>

我想在那里进行测试。我在tests/unit 文件夹中有文件table.spec.js

import  expect  from 'chai'
import  shallowMount, createLocalVue  from '@vue/test-utils'
import Vuex from 'vuex'
import Table from '@/components/Table.vue'
const localVue = createLocalVue()
localVue.use(Vuex)
const store = new Vuex.Store(
    state: 
)

describe('Table.vue', () => 
    it('renders h1 tag', () => 
    const wrapper = shallowMount(Table, localVue, store)
    expect(wrapper.find('h1').text().equal('Table'))
)
)

当我运行命令npm run test:unit 时出现错误1) Table.vue renders h1 tag: TypeError: Cannot read property 'table' of undefined 以前是文本错误Cannot read property 'state' of undefined

我试图在测试中包含 vuex,但这是我第一次使用单元测试,看起来我做错了什么

我需要通过我的测试,也许有人可以帮助我为某些事件编写新测试,例如单击按钮并调用操作。提前致谢

【问题讨论】:

【参考方案1】:

你必须通读https://vue-test-utils.vuejs.org/guides/using-with-vuex.html

他们有很好的模拟 vuex 的例子,这是你需要做的。它看起来像这样:

import  shallowMount, createLocalVue  from '@vue/test-utils'
import Vuex from 'vuex'
import Actions from '../../../src/components/Actions'

const localVue = createLocalVue()

localVue.use(Vuex)

describe('Actions.vue', () => 
  let actions
  let store

  beforeEach(() => 
    actions = 
      actionClick: jest.fn(),
      actionInput: jest.fn()
    
    store = new Vuex.Store(
      actions
    )
  )

  it('dispatches "actionInput" when input event value is "input"', () => 
    const wrapper = shallowMount(Actions,  store, localVue )
    const input = wrapper.find('input')
    input.element.value = 'input'
    input.trigger('input')
    expect(actions.actionInput).toHaveBeenCalled()
  )

【讨论】:

如何用摩卡代替这个? actionClick: jest.fn(), actionInput: jest.fn() 我相信很多人在使用 Mocha 时都会使用 sinon 中的 spy() 方法来模拟函数。这是一个完全不同的图书馆。

以上是关于如何解决 vuex 和单元测试的问题?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 VueJS 中对 Vuex 动作进行单元测试

如何在 Mocha 单元测试中访问命名空间的 Vuex getter

Vue 单元测试:如何使用 props、vuex store、watchers、getter 等测试复杂组件

为啥 VueX 存储在多个单元测试中保留状态?

如何使用 vue-test-utils 和 Jest 在 Nuxt 中对使用 vuex-module-decorators 语法定义的 Vuex 模块进行单元测试?

使用 Vuex 时如何测试 Vuejs 组件