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);
});
});