前言
在往期的文章中,我们已经对常见的各种组件测试,各种用户行为,mock等等进行了学习。在我们的实际开发中,我们除了组件之外,还会写一些自定义的hook,针对这些自定义的hook我们也可以写对应的单测,这一篇我们就来写一下关于hook的单测
新增hook
我们依旧沿用之前的项目,在项目中创建一个hook目录,来放置我们的自定义hook,这里实现了一个类似于 Arco Design useCheckbox 的一个hook
cd src
mkdir hooks
cd hooks
touch useCheckbox.ts
useCheckbox.ts
import { useState } from 'react';
export default function useCheckbox<T>(
values: T[],
checkboxKey: keyof T,
defaultSelected?: T[],
) {
// 选中项
const [selected, setSelected] = useState<T[]>(defaultSelected ?? []);
// 判断该选项是否被选中
function isSelected(checkItem: T) {
return selected.some(item => {
return item[checkboxKey] === checkItem[checkboxKey];
});
}
// 判断是否全部被选中
function isAllSelected() {
return values.every(item => isSelected(item));
}
// 是否只有部分选项选中
function isPartialSelected() {
const checkHasSelected = values.some(item => isSelected(item));
// 有一部分被选中但是又不是全部都选中
return checkHasSelected && !isAllSelected();
}
// 选中全部
function selectAll() {
setSelected(values);
}
// 取消全部选中
function unSelectAll() {
setSelected([]);
}
return {
selected,
setSelected,
isAllSelected,
isPartialSelected,
selectAll,
unSelectAll,
isSelected,
}
}
这里注释都写的挺清晰的,我们就不再进行走读,基本上就是封装了常见的checkbox的一些便捷操作
添加依赖
对hook进行单测编写的话我们需要增加@testing-library/react-hooks
这个包,原先我们是没有引入的,现在我们添加一下
pnpm add @testing-library/react-hooks
编写单测
我们还是保持跟之前的风格一样,就是在hooks目录新建一个__tests__
目录,放置我们的单测
useCheckbox.test.ts
import useQueryCheckbox from '../useCheckbox';
import { renderHook } from '@testing-library/react-hooks';
interface MockCheckboxItemProps {
key: string;
value: string;
}
// 获取用于测试的默认checkbox对象列表
function generateCheckboxList(endIndx: number, startIndex = 1) {
const defaultCheckboxList: MockCheckboxItemProps[] = [];
for (let i = startIndex; i <= endIndx; i++) {
defaultCheckboxList.push({
key: `${i}`,
value: `mock-${i}`,
});
}
return defaultCheckboxList;
}
describe('hook useQueryCheckbox', () => {
it('should return the total selected item', () => {
const checkboxList = generateCheckboxList(8);
const { result } = renderHook(() => useQueryCheckbox(checkboxList, 'key'));
const { selected } = result.current;
expect(selected).toEqual([]);
});
it('should return the total default selected item', () => {
const checkboxList = generateCheckboxList(8);
const { result } = renderHook(() =>
useQueryCheckbox(checkboxList, 'key', checkboxList),
);
const { selected } = result.current;
expect(selected).toEqual(checkboxList);
});
});
简单走读一下,这里我们我们需要用到renderHook
这个api来为我们提供hook的运行环境,之后我们就可以同正常使用hook那样对操作hook,这里我们就只模拟了初始化的场景,最后对我们的selected进行断言,其他的单测逻辑同我们之前的文章大同小异,这里就只写了两个用例作为例子。
运行一下看看
pnpm test -- src/hooks/__tests__/useCheckbox.test.ts
可以看到运行通过,我们的hook单测也到这一步
结尾
react hook的单测也是比较常见的,实际工作中可能会有同学比较抗拒这一块的单测,本文做了简单的介绍和实践,其他相关的一些方法可以看往期的文章介绍
传送门
前端单测学习(1)—— 单测入门之react单测项目初步
前端单测学习(2)—— react 组件单测初步
前端单测学习(3)—— react组件单测进阶
前端单测学习(4)—— react 组件方法&fireEvent
前端单测学习(5)—— 快照
前端单测学习(6)—— 定时器
前端单测学习(7)—— mock
前端单测学习(8)—— react hook
前端单测学习(9)—— 覆盖率报告
前端单测学习(10)—— 状态管理redux
前端单测学习(11)—— react hook 进阶
前端单测学习(12)—— 性能优化
前端单测学习(13)—— 自动化测试