I have a React Native component with a TextInput that I’m testing. Part of the behaviour of this component relies on handling the current selection position via onSelectionChange — that is, it matters where the text cursor is in the text field as we type.
That component looks basically like this:
type Selection = { start: number, end?: number };
const Component = () => {
const [value, setValue] = useState("");
const [selection, setSelection] = useState<Selection>({ start: 0, end: 0 });
// do some things with value and selection, e.g.:
useEffect(() => {
console.debug(value.slice(selection.start, selection.end));
}, [value, selection.start, selection.end]);
return (
<TextInput
testID="input"
value={text}
onChangeText={setMessageText}
selection={selection}
onSelectionChange={setSelection}
/>
);
}
In our unit tests for this component I can change the value just fine to test the behaviour associated with the value (via React Native Testing Library’s fireEvent.changeText):
const input = screen.getByTestId("input");
fireEvent.changeText(input, "some text");
However changing the text doesn’t move the text cursor, so the selection
always remains as { start: 0 }
. To properly test the behaviour of this component, I need to be able to set the selection to other positions. This means I need my code to somehow call setSelection({ start: 3, end: 3 })
and so on after value
changes.
How can I get the onSelectionChange event to fire in my unit tests?
I think this issue is essentially one of two things:
- How can I fire a selection change event such that it will surface from
onSelectionChange
? - Alternately, how do I access the function that was bound to the TextInput’s
onSelectionChange
property so as to call it directly?
Should I just be setting up a jest mock for <TextInput />
with something that automatically updates the selection when the text changes?