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);
    });
});
相关推荐
LYFlied几秒前
前端技术风险防控:以防为主,防控结合
前端·工程化·技术风险防控
小圣贤君几秒前
从零到一:打造专业级小说地图设计工具的技术实践
vue.js·electron·写作·canvas·小说·小说地图
宁雨桥2 分钟前
前端跨页面通信:从基础到工程化的全面指南
前端·vue.js·react.js
梵尔纳多3 分钟前
electron 安装
前端·javascript·electron
心.c8 分钟前
初步了解Next.js
开发语言·前端·javascript·js
挫折常伴左右9 分钟前
初见HTML
前端·html
阿蓝灬11 分钟前
详述单点登录(SSO)
前端
灵感__idea15 分钟前
Hello 算法:以“快”著称的哈希
前端·javascript·算法
恋猫de小郭18 分钟前
Flutter 官方正式解决 WebView 在 iOS 26 上有点击问题
android·前端·flutter
阿珊和她的猫1 小时前
CSS3新特性概述
前端·css·css3