I'm using this library for select/options and I'd like to unit test certain things like if there's the disabled passed to it, prevent it from changing the value.
So far, I tried something like this:
Component:
import React, {useState, useEffect} from 'react';
import {View} from 'react-native';
import RNPickerSelect from 'react-native-picker-select';
export default function PickerInput(props) {
const [pickerItems, setPickerItems] = useState([]);
const [selectedIndex, setSelectedIndex] = useState(0);
const [placeholder, setPlaceholder] = useState({});
const [error, setError] = useState(false);
const [enabled, setEnabled] = useState(true);
useEffect(() => {
// loop over options prop and construct the array
const pickerItemsArray = [];
if (
Array.isArray(props.options) &&
props.options.length &&
props.selectedIndex >= 0
) {
props.options.map((option, index) => {
pickerItemsArray.push({
label: option,
value: index,
});
});
}
// push the constructed array
{
pickerItemsArray.length
? setPickerItems(pickerItemsArray)
: setPickerItems([]);
}
// check if placeholder prop has a value and pass it, else pass empty object to prevent the picker from showing a placeholder
{
props.placeholder &&
setPlaceholder({
label: props.placeholder,
value: null,
});
}
{
setError(props.error);
}
{
!props.enabled ? setEnabled(false) : setEnabled(true);
}
}, []);
useEffect(() => {
props.selectedIndex < 0 && setSelectedIndex(-1);
// check if selectedIndex prop is larger than the options prop and set it to the length of options prop, else pass the selectedIndex prop
{
Array.isArray(props.options) &&
props.options.length - 1 < props.selectedIndex &&
props.selectedIndex >= 0
? setSelectedIndex(props.options.length - 1)
: setSelectedIndex(props.selectedIndex);
}
}, [selectedIndex]);
const onValueChange = value => {
if ((value === 0 || value) && props.enabled) {
setSelectedIndex(value);
props.onValueChange(pickerItems[value].label);
} else {
setSelectedIndex(null);
}
};
return (
<View
testID="picker-wrapper">
<RNPickerSelect
onValueChange={value => onValueChange(value)}
items={pickerItems}
disabled={!enabled}
placeholder={placeholder}
value={selectedIndex}
/>
</View>
);
}
Test:
...
it('should not make the component change value when enabled is false', () => {
const props = {
placeholder: 'Select',
options: ['testOption', 'testOption2'],
selectedIndex: 0,
error: false,
enabled: false,
};
const newSelectedIndex = 1;
const {queryByTestId} = render(
<PickerInput {...props} onValueChange={true} />,
);
const pickerWrapper = queryByTestId('picker-wrapper');
pickerWrapper.props.children.props.value = newSelectedIndex
expect(pickerWrapper.props.children.props.value).toBe(
props.selectedIndex,
);
});
I'm pretty new to react native and also testing, is this the best way to achieve this? Shouldn't there be a fireEvent where I fire the event of changing the value? I can't seem to find any. Would really appreciate someone's help.