React Native单元测试:如何修改TextInput选区并触发onSelectionChange事件
React Native单元测试:如何修改TextInput选区并触发onSelectionChange事件
我明白你现在的困扰——要测试依赖TextInput选区变化的组件,关键就是怎么在测试里模拟选区修改并触发onSelectionChange对吧?别担心,我来一步步教你怎么搞定这个事儿。
首先先把你的组件代码补全(你之前的代码有点截断啦),方便后续理解:
type Selection = { start: number, end?: number }; const Component = () => { const [value, setValue] = useState(""); const [selection, setSelection] = useState<Selection>({ start: 0, end: 0 }); // 基于value和selection做一些逻辑,比如打印选中的文本 useEffect(() => { console.debug(value.slice(selection.start, selection.end)); }, [value, selection.start, selection.end]); const onSelectionChange = (event: NativeSyntheticEvent<TextInputSelectionChangeEventData>) => { const { start, end } = event.nativeEvent.selection; setSelection({ start, end }); }; return ( <TextInput value={value} onChangeText={setValue} onSelectionChange={onSelectionChange} editable /> ); };
接下来是核心的测试方案,我们用@testing-library/react-native这个工具库来实现,它能帮我们轻松模拟组件事件:
基础测试步骤
- 首先确保你已经安装了依赖:
npm install --save-dev @testing-library/react-native jest
- 编写测试代码,核心是用
fireEvent模拟onSelectionChange事件,并传入自定义的选区数据:
import { render, screen, fireEvent } from '@testing-library/react-native'; import Component from './Component'; describe('TextInput Selection Handling', () => { it('triggers onSelectionChange and updates selection state', () => { // 渲染组件 render(<Component />); // 找到页面上的TextInput元素 const textInput = screen.getByRole('textbox'); // 模拟选区变化:假设我们选中从索引2到5的文本 fireEvent(textInput, 'onSelectionChange', { nativeEvent: { selection: { start: 2, end: 5 }, }, }); // 这里可以添加断言来验证逻辑是否正确执行 // 比如我们监听console.debug,检查它是否输出了预期的内容 const consoleSpy = jest.spyOn(console, 'debug').mockImplementation(); // 重新渲染组件触发useEffect(如果需要的话) render(<Component />); // 因为初始value是空字符串,所以slice(2,5)结果为空 expect(consoleSpy).toHaveBeenCalledWith(''); // 清理mock consoleSpy.mockRestore(); }); });
进阶场景测试(比如结合文本内容)
如果你的组件需要结合输入框的文本内容处理选区,比如替换选中的文本,你可以先设置输入框的值,再模拟选区变化:
it('handles selection with existing text correctly', () => { render(<Component />); const textInput = screen.getByRole('textbox'); // 先给输入框设置文本内容 fireEvent.changeText(textInput, 'Hello React Native'); // 模拟选中"React"这个词(索引6到11) fireEvent(textInput, 'onSelectionChange', { nativeEvent: { selection: { start: 6, end: 11 } }, }); // 监听console.debug,检查是否输出了选中的"React" const consoleSpy = jest.spyOn(console, 'debug').mockImplementation(); render(<Component />); expect(consoleSpy).toHaveBeenCalledWith('React'); consoleSpy.mockRestore(); });
关键注意点
- React Native的
onSelectionChange事件参数是NativeSyntheticEvent,所以模拟的时候必须把选区数据放在nativeEvent.selection里,否则组件无法正确解析。 - 如果你需要测试光标单独定位(非选中状态),只需要让
start和end的值相同即可,比如{ start: 3, end: 3 }。
备注:内容来源于stack exchange,提问作者Autumn Leaf
相关产品推荐
相关产品推荐

