You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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这个工具库来实现,它能帮我们轻松模拟组件事件:

基础测试步骤

  1. 首先确保你已经安装了依赖:
npm install --save-dev @testing-library/react-native jest
  1. 编写测试代码,核心是用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.16 09:13:08