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?Solutionsource: stackoverflow \u2197
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/bc6eee19aa30d69dd6809ab1dd4ba67a94d187fef1d947b084465a87bc52cd82hash \u00b7 bc6eee19aa30d69dd6809ab1dd4ba67a94d187fef1d947b084465a87bc52cd82