3

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

2 Answers 2

3

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

Sign up to request clarification or add additional context in comments.

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.