Berni
Berni

Reputation: 258

Testing Vue Router in component navigation guard

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

Answers (2)

Pallamolla Sai
Pallamolla Sai

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

Berni
Berni

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

Related Questions