如何用Jest测试Vue3中onBeforeRouteLeave关联的doSomething函数
解决Vue Router onBeforeRouteLeave钩子关联函数的测试覆盖问题
你当前的问题在于,mock的onBeforeRouteLeave只是一个空的jest函数,并没有执行它接收的回调(也就是你的doSomething),所以这个函数的逻辑没被触发,自然不会被测试覆盖。可以按以下步骤修正:
1. 提取被注册的回调函数
挂载组件后,从mock的onBeforeRouteLeave中取出它被调用时传入的doSomething回调:
import { mount } from '@vue/test-utils' import { onBeforeRouteLeave } from 'vue-router' import YourComponent from './YourComponent.vue' // 保持你的mock不变 jest.mock('vue-router', () => ({ onBeforeRouteLeave: jest.fn(), onBeforeRouteUpdate: jest.fn(), })) test('验证onBeforeRouteLeave与doSomething的关联', () => { // 挂载组件,此时setup会执行,onBeforeRouteLeave会被调用并传入doSomething const wrapper = mount(YourComponent, { global: { emits: ['close'] // 声明组件用到的emit,避免警告 } }) // 获取onBeforeRouteLeave的第一个调用参数,也就是doSomething函数 const doSomething = onBeforeRouteLeave.mock.calls[0][0] })
2. 测试doSomething的不同分支逻辑
拿到回调后,模拟active的不同状态,验证函数的返回值和触发的行为:
注意:如果
active是组件内部的ref,需要在组件中通过defineExpose暴露它,才能在测试中修改:
组件setup末尾添加:defineExpose({ active })
test('验证onBeforeRouteLeave与doSomething的关联', () => { const wrapper = mount(YourComponent, { global: { emits: ['close'] } }) const doSomething = onBeforeRouteLeave.mock.calls[0][0] // 测试active为true的情况 wrapper.vm.active = true const resultActive = doSomething() expect(resultActive).toBe(false) expect(wrapper.emitted('close')).toHaveLength(1) // 验证close事件被触发 // 测试active为false的情况 wrapper.vm.active = false const resultInactive = doSomething() expect(resultInactive).toBe(true) expect(wrapper.emitted('close')).toBeUndefined() // 验证close事件未触发 })
3. 验证钩子的注册行为
最后,确认onBeforeRouteLeave确实被正确调用了一次,且传入了函数类型的参数:
expect(onBeforeRouteLeave).toHaveBeenCalledTimes(1) expect(onBeforeRouteLeave).toHaveBeenCalledWith(expect.any(Function))
内容的提问来源于stack exchange,提问作者niepl
相关产品推荐
相关产品推荐

