在组件导航防护中测试Vue Router

时间:2018-06-18 16:02:24

标签: vue.js vue-router vue-test-utils

我尝试对一个组件进行单元测试(使用vue-test-utils),组件导航Guard中有一个beforeRouteUpdate,如下所示:

<template>
   ...
</template>
<script>
export default {
    computed: {
        ...
    }
    ...
    beforeRouteUpdate(to, from, next) {
        // code to be tested
        this.$store.dispatch('setActiveTask')
    }
}
</script>

我使用shallowMount渲染测试文件中的组件并模拟$store之类的内容。

beforeEach(() => {
    cmp = shallowMount(Task, {
                mocks: {
                    $store: store,
                    $route: {
                        params: {
                            taskID: 12,
                            programID: 1
                        }
                    }
                },
                i18n: new VueI18N({
                    silentTranslationWarn: true
                }),
                stubs: {
                    'default-layout': EmptySlotComponent,
                    'nested-router': EmptySlotComponent,
                    RouterLink: RouterLinkStub
                }
            })
})

it('has beforeRouteUpdate hook', () => {
    // how do i call beforeRouteUpdate now?
    // cmp.vm.beforeRouteUpdate(...)
}

有没有人对此有所了解?

更新: 我创建了一个使用@vue/cli和Mocha + Chai作为单元测试工具的最小示例,可以在此处找到:https://github.com/BerniWittmann/vue-test-navigation-guard-reproduction

2 个答案:

答案 0 :(得分:2)

让它正常工作,但是提供了一种解决方案。 我的测试现在看起来像这样:

it('test', () => {
    const beforeRouteUpdate = wrapper.vm.$options.beforeRouteUpdate
    const $store = {
        dispatch: () => {
        }
    }
    spyOn($store, 'dispatch').and.returnValue({ then: (arg) => arg() })

    let next = jasmine.createSpy('next')
    render()

    beforeRouteUpdate.call({ $store }, {
        params: {
            taskID: 1
        }
    }, {}, next)

    expect($store.dispatch).toHaveBeenCalledWith('setActiveTask', 1)
    expect(next).toHaveBeenCalled()
})

wrapper.vm.$options.beforeRouteUpdate中提供了导航卫士,但是调用它我失去了this的上下文,因此我无法在组件导航卫士中调用this.$store.dispatch,这就是为什么我需要使用.call()方法

答案 1 :(得分:0)

下面的代码对我来说可以很好地测试路线导航卫士。

const beforeRouteUpdate = wrapper.vm.$options.beforeRouteUpdate[0];
let nextFun = jest.fn();
beforeRouteUpdate.call(wrapper.vm , "toObj", "fromObj", nextFun); 

testing route navigation guards git hub

how to test vue router beforeupdate navigation guard