如何为含onClick方法的Hooks编写测试?日期选择器选值激活保存按钮测试
React Hooks onClick 测试方案
1. 带onClick方法的Hooks测试方法
不管是组件内的onClick逻辑,还是自定义Hook暴露的onClick函数,都可以用React Testing Library结合Jest完成测试,核心是模拟用户行为并断言结果:
场景1:组件内的onClick事件
如果onClick是组件内的事件处理函数,比如按钮点击触发状态更新:
// 组件示例 function Counter() { const [count, setCount] = useState(0); const handleClick = () => setCount(count + 1); return <button onClick={handleClick}>Count: {count}</button>; } // 测试代码 import { render, screen, fireEvent } from '@testing-library/react'; import Counter from './Counter'; test('点击按钮后计数加1', () => { render(<Counter />); const button = screen.getByText(/count:/i); // 模拟点击 fireEvent.click(button); // 断言结果 expect(button).toHaveTextContent('Count: 1'); });
场景2:自定义Hook的onClick函数
如果是自定义Hook返回onClick方法和状态,用renderHook来测试:
// 自定义Hook示例 function useCounter() { const [count, setCount] = useState(0); const increment = () => setCount(count + 1); return { count, increment }; } // 测试代码 import { renderHook, act } from '@testing-library/react'; import useCounter from './useCounter'; test('调用increment后计数加1', () => { const { result } = renderHook(() => useCounter()); // 触发onClick逻辑(这里是increment) act(() => { result.current.increment(); }); // 断言状态变化 expect(result.current.count).toBe(1); });
2. 日期选择后激活保存按钮的测试方案
结合你提供的状态更新逻辑,测试核心是验证日期选择后,selectedDate状态正确更新,且保存按钮从禁用变为启用:
测试步骤及代码示例
假设你的组件结构如下(包含日期选择器和保存按钮):
function AnniversaryForm({ employeeId }) { const [selectedDate, setSelectedDate] = useState([]); const [isDisabled, setIsDisabled] = useState(true); const handleDateChange = (value) => { // 你提供的状态更新逻辑 if (selectedDate?.filter((e) => e.employeeId === employeeId).length > 0) { setSelectedDate(selectedDate.map((e) => { if (e.employeeId === employeeId) { return { ...e, workAnniversary: value }; } else { return { ...e }; } })); } else { setSelectedDate([...selectedDate, { employeeId, workAnniversary: value }]); } setIsDisabled(false); }; return ( <div> <input type="date" onChange={(e) => handleDateChange(e.target.value)} /> <button disabled={isDisabled}>保存</button> </div> ); }
对应的测试代码:
import { render, screen, fireEvent } from '@testing-library/react'; import AnniversaryForm from './AnniversaryForm'; test('选择日期后保存按钮启用,且selectedDate状态更新', () => { const testEmployeeId = '123'; const testDate = '2020-01-01'; render(<AnniversaryForm employeeId={testEmployeeId} />); // 初始状态:保存按钮禁用 const saveButton = screen.getByText('保存'); expect(saveButton).toBeDisabled(); // 模拟日期选择 const dateInput = screen.getByRole('textbox'); // 根据实际选择器调整定位方式 fireEvent.change(dateInput, { target: { value: testDate } }); // 断言保存按钮启用 expect(saveButton).not.toBeDisabled(); // 可选:如果组件有展示selectedDate的元素,可断言内容是否正确 // expect(screen.getByText(testDate)).toBeInTheDocument(); });
关键注意点
- 不同UI库的日期选择器可能需要调整模拟方式,比如AntD的DatePicker需要触发
onChange事件并传入对应的moment对象 - 如果状态更新是异步的,用
waitFor包裹断言,确保状态更新完成后再检查 - 测试聚焦用户行为(选择日期→按钮启用),而非内部实现细节,符合React Testing Library的设计理念
内容的提问来源于stack exchange,提问作者Sreyash
相关产品推荐
相关产品推荐

