To test components with a real router instance, instantiate a new router object for each test using createRouter and createWebHistory. This prevents state leakage between tests.
When using a real router, you must:
- Register the router instance in the
global.plugins option of mount. - Use
await router.isReady() to ensure the router is fully initialized before proceeding. - Use
jest.spyOn(router, 'push') (or your runner's equivalent) to assert that navigation occurred.
Note that Vue Router 4 is asynchronous, so ensure your test handles the router's lifecycle correctly.
import { mount } from '@vue/test-utils'
import { createRouter, createWebHistory } from 'vue-router'
import { routes } from '@/router'
let router
beforeEach(async () => {
router = createRouter({
history: createWebHistory(),
routes: routes
})
router.push('/')
await router.isReady()
})
test('allows authenticated user to edit a post', async () => {
const wrapper = mount(Component, {
props: { isAuthenticated: true },
global: {
plugins: [router]
}
})
const push = jest.spyOn(router, 'push')
await wrapper.find('button').trigger('click')
expect(push).toHaveBeenCalledWith('/posts/1/edit')
})