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);
    });
});
相关推荐
风骏时光牛马8 小时前
AI稳定性治理体系构建与疑难问题深度分析
前端
IT_陈寒9 小时前
JavaScript的this坑人实录,这次我真的记下来了
前端·人工智能·后端
开开心心就好10 小时前
音频降噪剪辑工具,音量裁剪一键处理
运维·服务器·前端·spring·ocr·音视频·1024程序员节
PedroQue9912 小时前
0.8.2 新增 backFallback 配置,无 tabbar 页返回无忧
前端·uni-app
淡漠的蓝精灵12 小时前
web.py:一个简单到极致的 Python Web 框架
开发语言·前端·python·其他
开开心心就好12 小时前
竖式除法出题工具,整除余数混合模式
运维·服务器·前端·javascript·ocr·perl·1024程序员节
起个名字费劲死了13 小时前
Halcon学习一:骰子识别
前端·python·学习
大江东去浪淘尽千古风流人物13 小时前
【HexVIO】DSP卸载双目惯性VIO:Hexagon向量化前端与单帧融合调度深度解析
前端·状态模式·slam·dsp·vio·hexagon·移动端加速
其实防守也摸鱼13 小时前
Chrome 扩展安全攻防实录:从攻击面到防御实践
开发语言·前端·网络·chrome·安全·web安全·php
web打印社区13 小时前
Lodop排障总纲-常见报错一张表
开发语言·前端·javascript·chrome·websocket