hnrd
hnrd

Reputation: 335

Mocking vue-router's useRoute() in Jest tests in Vue 3

I'm using Vue 3 and Vue-Router for my app, and I'm having trouble when creating unit tests with Jest on components that use useRoute(), such as the following:

<template>
    <div :class="{ 'grey-background': !isHomeView }" />
</template>

<script lang="ts">
import { defineComponent, computed } from 'vue';
import { useRoute } from 'vue-router';

export default defineComponent({
    setup: () => {
        const isHomeView = computed(() => {
            return useRoute().name === 'Home';
        });

        return {
            isHomeView,
        };
    },
});
</script>

The computed property is using useRoute(), and it is used in the template. When I make a Jest test on this component, an error is thrown saying TypeError: Cannot read property 'name' of undefined.

I tried mocking useRoute like so : jest.mock('vue-router', () => ({ useRoute: jest.fn() })); and then on the beforeEach: useRoute.mockReturnValueOnce({ name: 'Home' });, but it doesn't work.

I'm not talking about Vue 2 in which the router works differently but Vue 3.

Upvotes: 7

Views: 7944

Answers (1)

tony19
tony19

Reputation: 138326

The problem is your factory function (i.e., in { useRoute: jest.fn() }) has no mock return specified (i.e., it returns undefined), so useRoute().name is trying to access name from undefined, which generates the error you mentioned.

You could either update the mock factory to return an object with a name property:

jest.mock('vue-router', () => ({
  useRoute: jest.fn(() => ({ name: 'Home' }))
}))

...or mock them inside the tests instead of using the factory:

jest.mock('vue-router')

describe('MyFoo.vue', () => {

  it('should have grey background for Home view', () => {
    require('vue-router').useRoute.mockReturnValueOnce({ name: 'Home' })
    const wrapper = shallowMount(MyFoo)
    expect(wrapper.html()).not.toContain('grey-background')
  })

  it('should not have grey background for non-Home view', () => {
    require('vue-router').useRoute.mockReturnValueOnce({ name: 'About' })
    const wrapper = shallowMount(MyFoo)
    expect(wrapper.html()).toContain('grey-background')
  })
})

Upvotes: 13

Related Questions