npmunit-testing80% confidence\u2191 8

Vitest error "TypeError: Cannot read properties of undefined (reading 'resolve')" (router.resolve)

Full error message
I have a very basic test, however it throws the error below when I try to mount a component const wrapper = mount(HomeHeader). I've pasted my vite config, test, component and packages.

This error happened without updating my vite config, but I went ahead and updated the config with test: { globals: true, } so I don't have to import test and expect.

Full error

stderr | src/components/home/__tests__/HomeHeader.test.js > HomeHeader renders properly
[Vue warn]: injection "Symbol([vue-router]: router)" not found.
  at <RouterLink to="/" >
  at <HomeHeader ref="VTU_COMPONENT" >
  at <VTUROOT>
[Vue warn]: injection "Symbol([vue-router]: route location)" not found.
  at <RouterLink to="/" >
  at <HomeHeader ref="VTU_COMPONENT" >
  at <VTUROOT>
[Vue warn]: Unhandled error during execution of setup function
  at <RouterLink to="/" >
  at <HomeHeader ref="VTU_COMPONENT" >
  at <VTUROOT>

FAIL  src/components/home/__tests__/HomeHeader.spec.js > HomeHeader > renders properly
TypeError: Cannot read properties of undefined (reading 'resolve')
 ❯ ReactiveEffect.fn node_modules/vue-router/dist/vue-router.cjs.js:2068:45
    2066|     const router = vue.inject(routerKey);
    2067|     const currentRoute = vue.inject(routeLocationKey);
    2068|     const route = vue.computed(() => router.resolve(vue.unref(props.to)));
       |                                             ^

Vitest UI

Vite Config

import { fileURLToPath, URL } from 'url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'

// https://vitejs.dev/config/
export default defineConfig({
  test: {
    globals: true,
  },
  plugins: [vue(), vueJsx()],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url)),
    },
  },
})

My test

import { mount } from '@vue/test-utils'
import HomeHeader from '../HomeHeader.vue'

describe('HomeHeader', () => {
  it('renders properly', () => {
    // This breaks
    const wrapper = mount(HomeHeader)
    expect(wrapper.text()).toContain('MOONHOLDINGS.XYZ')
  })
})

The component being tested

<script setup>
import { RouterLink } from 'vue-router'
import {
  MOON_XYZ,
  LOGIN,
  LOGIN_PATH,
  GET_STARTED,
  SIGN_UP_PATH,
} from '../../constants'
import PrimaryBtn from '@/components/partials/PrimaryBtn.vue'
</script>

<template>
  <main>
    <header>
      <h1>
        <RouterLink to="/">
          {{ MOON_XYZ }}
        </RouterLink>
      </h1>
      <nav>
        <RouterLink :to="LOGIN_PATH">{{ LOGIN }}</RouterLink>
        <PrimaryBtn :copy="GET_STARTED" :url="SIGN_UP_PATH" />
      </nav>
    </header>
  </main>
</template>

<style lang="scss" scoped>
h1 {
  margin: 1em;
  font-size: 1.375rem;
  color: #fff;
}

a {
  color: #fff;
  text-decoration: none;
}

nav {
  position: absolute;
  right: 2em;

  a {
    display: inline-block;
    padding: 0 1rem;
    font-size: 2em;
    text-decoration: none;
    color: #fff;
    transition: 0.4s;

    .router-link-exact-active {
      color: #fff;
    }

    .router-link-exact-active:hover {
      background-color: transparent;
    }

    &:hover {
      text-decoration: underline;
    }

    &:first-of-type {
      border: 0;
    }
  }
}

@media (min-width: 1024px) {
  header {
    display: flex;
    place-items: center;
    padding-right: calc(var(--section-gap) / 2);
  }
}
</style>

Script command "coverage": "vitest run --coverage",

My dependencies

"dependencies": {
  "animate.css": "^4.1.1",
  "axios": "^0.27.2",
  "pinia": "^2.0.14",
  "vue": "^3.2.36",
  "vue-router": "^4.0.15"
},
"devDependencies": {
  "@rushstack/eslint-patch": "^1.1.0",
  "@vitejs/plugin-vue": "^2.3.3",
  "@vitejs/plugin-vue-jsx": "^1.3.10",
  "@vitest/ui": "^0.20.3",
  "@vue/eslint-config-prettier": "^7.0.0",
  "@vue/test-utils": "^2.0.2",
  "c8": "^7.11.3",
  "eslint": "^8.5.0",
  "eslint-plugin-vue": "^9.0.0",
  "happy-dom": "^6.0.4",
  "jsdom": "^19.0.0",
  "npm-run-all": "^4.1.5",
  "prettier": "^2.5.1",
  "ramda": "^0.28.0",
  "sass": "^1.53.0",
  "start-server-and-test": "^1.14.0",
  "vite": "^2.9.9",
  "vitest": "^0.20.3",
  "vue-tsc": "^0.35.2"
}

Anyone else run into this before while using Vitest?

Vue Router is automatically mocked and because of that, no methods can be called from it. That's the reason why you are getting errors on calling resolve(). Correct test should look like this: import { vi } from 'vitest'; import { mount } from '@vue/test-utils' import HomeHeader from '../HomeHeader.vue' // you need to mock router vi.mock('vue-router', () => ({ resolve: vi.fn(), })); describe('HomeHeader', () => { it('renders properly', () => { const wrapper = mount(HomeHeader) expect(wrapper.text()).toContain('MOONHOLDINGS.XYZ') }) })

API access

Get this solution programmatically \u2014 free, no authentication.

curl https://depscope.dev/api/error/bc6eee19aa30d69dd6809ab1dd4ba67a94d187fef1d947b084465a87bc52cd82
hash \u00b7 bc6eee19aa30d69dd6809ab1dd4ba67a94d187fef1d947b084465a87bc52cd82
Vitest error &quot;TypeError: Cannot read properties of unde… — DepScope fix | DepScope