如何测试带:to属性的Vuetify v-btn路由跳转(Vue2+Jest)
Vuetify v-btn :to 属性的路由跳转测试问题及解决方法
问题场景
在Vue 2、Vuetify 2、vue-router、jest、vue-test-utils环境下,测试带:to属性的v-btn点击后的路由跳转行为时遇到两个问题:
- 测试代码中mock的
$router.push始终未被调用,报错显示调用次数为0(预期1次),但改用@click手动触发this.$router.push时测试能正常通过。 - 尝试断言
:to属性内容时,获取到的结果是字符串"[object Object]",无法匹配预期的路由对象。
按钮代码:
<v-btn id="create-plan-btn" :to="{ 'name': 'newPlan', query: { dept: 216001 }}">Create plan</v-btn>
原测试失败的核心表现:mock的$router.push未捕获到跳转调用,断言:to属性时类型不匹配。
解决方法
1. 正确捕获:to触发的路由跳转
Vuetify的v-btn绑定:to时,内部是基于router-link的逻辑实现跳转,并非直接通过click事件调用$router.push。调整测试逻辑如下:
- 替换
shallowMount为mount:shallowMount会stub子组件,截断v-btn内部依赖的路由跳转逻辑 - 直接用
trigger('click')触发真实点击:无需手动$emit('click'),:to绑定会自动关联路由跳转逻辑 - 给
localVue注册vue-router:确保路由相关逻辑能正常运行
修改后的测试代码:
import VueRouter from 'vue-router' import { createLocalVue, mount } from '@vue/test-utils' import Vuetify from 'vuetify' import StudentLanding from '@/components/StudentLanding.vue' describe('点击"Create Plan"按钮时', () => { const localVue = createLocalVue() let vuetify let mockRouter // 给localVue注册vue-router localVue.use(VueRouter) beforeEach(() => { vuetify = new Vuetify() mockRouter = { push: jest.fn() } }) const $route = { path: '/student/index', name: 'studentLanding' } it('触发路由跳转到新建计划页面', async () => { const wrapper = mount(StudentLanding, { localVue, vuetify, mocks: { $route: $route, $router: mockRouter } }) const button = wrapper.find('#create-plan-btn') expect(button.exists()).toBe(true) expect(mockRouter.push).toHaveBeenCalledTimes(0) // 直接触发按钮的click事件 await button.trigger('click') await wrapper.vm.$nextTick() expect(mockRouter.push).toHaveBeenCalledTimes(1) expect(mockRouter.push).toHaveBeenCalledWith({ name: 'newPlan', query: { dept: 216001 } }) }) })
2. 正确断言:to属性的内容
attributes('to')会把绑定的对象转成字符串输出,无法直接匹配对象。可以通过按钮实例的$attrs获取原始绑定的:to对象:
// 正确的断言方式 expect(button.vm.$attrs.to).toEqual({ name: 'newPlan', query: { dept: 216001 } })
内容的提问来源于stack exchange,提问作者Ravioli87
相关产品推荐
相关产品推荐

