Reputation: 258
I'm trying to unit test (with vue-test-utils
) a component, which has a beforeRouteUpdate
in component navigation Guard like this:
<template>
...
</template>
<script>
export default {
computed: {
...
}
...
beforeRouteUpdate(to, from, next) {
// code to be tested
this.$store.dispatch('setActiveTask')
}
}
</script>
I do render the component in the test file with shallowMount
and mock stuff like the $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(...)
}
Has anyone some ideas about this?
UPDATE:
I created a minimal example with @vue/cli
and Mocha + Chai as unit test tools, which can be found here: https://github.com/BerniWittmann/vue-test-navigation-guard-reproduction
Upvotes: 3
Views: 3327
Reputation: 2493
Following code worked fine for me for testing route navigation guards.
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
Upvotes: 0
Reputation: 258
Got it working, but with a kind of hacky solution. my test now looks like this:
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()
})
The navigation guard is available in wrapper.vm.$options.beforeRouteUpdate
, but calling this I lost the context of this
so I was not able to call this.$store.dispatch
in the component navigation guard, thats why I needed to use the .call()
method
Upvotes: 3