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);
    });
});
相关推荐
AC赳赳老秦7 分钟前
Prometheus + DeepSeek:自动生成巡检脚本与告警规则配置实战
前端·javascript·爬虫·搜索引擎·prometheus·easyui·deepseek
接着奏乐接着舞。9 分钟前
前端大数据渲染性能优化:Web Worker + 分片处理 + 渐进式渲染
大数据·前端·性能优化
Beginner x_u17 分钟前
CSS 中的高度、滚动与溢出:从 height 到 overflow 的完整理解
前端·css·overflow·min-height
vx1_Biye_Design22 分钟前
基于web的物流管理系统的设计与实现-计算机毕业设计源码44333
java·前端·spring boot·spring·eclipse·tomcat·maven
tqs_1234529 分钟前
倒排索引数据结构
java·前端·算法
a程序小傲32 分钟前
听说前端又死了?
开发语言·前端·mysql·算法·postgresql·深度优先
Yan.love1 小时前
【CSS-布局】终极方案:Flexbox 与 Grid 的“降维打击”
前端·css
oscar9991 小时前
CI_CD 管道:是什么、为什么以及如何构建
ci/cd·单元测试·压力测试
请叫我聪明鸭1 小时前
基于 marked.js 的扩展机制,创建一个自定义的块级容器扩展,让内容渲染为<div>标签而非默认的<p>标签
开发语言·前端·javascript·vue.js·ecmascript·marked·marked.js插件
悟能不能悟1 小时前
Gson bean getxxx,怎么才能返回给前端
java·前端