vue hook单元测试

vue3 单元测试(hooks测试)

普通单元测试

typescript 复制代码
    function add(a: number, b: number) {
        return a + b;
    }
    expect(add(1, 2)).toEqual(3);

vue中的测试

vue的hook中存在vue的生命周期,所以需要hooks在vue中运行模拟整个生命周期

为hook提供组件环境

typescript 复制代码
import { mount } from '@vue/test-utils';
export function mountHook(hook: () => any, provide: { [key: string]: any } = {}) {
  return new Promise((resolve) => {
    const Comp = defineComponent({
      name: 'TestHookDepComponent',
      setup: () => {
        resolve(hook());
      },
      template: '<span>123</span>',
    });
    const ProviderComponent = defineComponent({
      name: 'TestHookProvideComponent',
      components: { TestHookDepComponent: Comp },
      provide: provide,
      setup: () => {},
      template: '<TestHookDepComponent />',
    });
    const comp = mount(ProviderComponent, { props: { name: '123' } });
    return comp;
  });
}

为了方便提供和修改hook中的其他依赖所以父组件提供ref等数据,子组件依赖的hook可获取到

测试纯hooks不依赖外部

typescript 复制代码
export function testHook() {
    const data = ref(1);
    const data1 = ref(data.value + 1);
    watch([data.value], () => {
        data1.value = data.value + 1;
    });
    return {
        updateData: (num: number) => {
            data.value = num;
        },
        data,
        data1
    }
}

普通hook测试

typescript 复制代码
import { mountHook } from './mountHook';
import { testHook } from './testHook';
describe('testHook', () => {
    it('test1', async() => {
        const handle = testHook(testHook);
        expect(handle.data.value).toEqual(1);
        expect(handle.data1.value).toEqual(2);
        handle.data.value = 2;
        await nextTrick();
        expect(handle.data1.value).toEqual(3);
        handle.update(4);
        await nextTrick();
        expect(handle.data1.value).toEqual(5);
    });
});

存在其他hook的依赖

不管vue和react都是倾向于组合式hook,所以真实开发情况都会存在外部hook的依赖,单元测试的目标是只测试自己的逻辑,无条件的信赖外部依赖

  • 第三方hook
typescript 复制代码
export function otherHook() {
    const dataRef = ref(1);
    onMounted(() => {
        dataRef.value = 2;
    });
    return {
        dataRef,
        update: () => {
            dataRef.value = 3;
        }
    }
}
  • 待测试的hooks
typescript 复制代码
import { otherHook } from './otherHook';
export function myHook() {
    const { dataRef, update} = otherHook();
    const myValue = ref(1);
    const myData = computed(() => {
        return dataRef.value + myValue.value;
    });
    return {
        myData,
        update: (val: number) => {
            myValue.value = val;
        }
    }
}
  • 测试
typescript 复制代码
import { vi } from 'vitest';
import { myHook } from './myHook';
describe('test myHook', () => {
    it('test', async () => {
        // 替换otherHook,让otherHook按照自己的预想逻辑运行
        vi.mock('./otherHook', () => {
            return {
                otherHook: () => {
                    const dataRef = ref(1);
                    return {
                        dataRef,
                        update: () => {}
                    }
                }
            }
        });
        const handle = testHook(myHook);
        await nextTrick();
        expect(handle.myData.value).toEqual(2);
        handle.update(2);
        await nextTrick();
        expect(handle.myData.value).toEqual(3);
    });
});
相关推荐
腻害兔1 小时前
【若依项目-产品经理视角】深度拆解 RuoYi-Vue-Pro 商城模块:从商品管理到交易引擎,50 张表撑起一整套电商系统
java·大数据·vue.js·产品经理·ai编程
不好听6131 小时前
从一行 JSX 到屏幕像素:前端开发者必须懂的浏览器渲染管线
前端
恒拓高科WorkPlus1 小时前
企业级内网即时通讯建设模型:BeeWorks内网IM四层架构
前端
前端小李子2 小时前
前端环境变量裸奔?我用 EnvShield 给它穿了件防弹衣
前端
youtootech2 小时前
HarmonyOS《柚兔学伴》项目实战25-我的页面、Web 嵌入与项目总结
前端·华为·harmonyos
小林ixn2 小时前
从零到一理解 React 父子组件通信:手写一个 Todo 应用带你彻底搞懂单向数据流
前端·javascript·react.js
醇氧4 小时前
CountDownLatch / CyclicBarrier / Semaphore 面试高频问答清单
前端·面试·职场和发展
qetfw5 小时前
MXU:Tauri 2 + React 的 MaaFramework 跨平台 GUI 源码
前端·python·react.js·前端框架·开源项目·效率工具
甲维斯5 小时前
我要开始吹牛逼了!Kimi K3 “宇宙无敌”!
前端·人工智能