'React-Native test an event with multiple state changes
I have written the following method inside of a react-native w/Typescript functional component. This series of state changes is accomplishing two things: 1.) it is taking from one array (linked to a .map() function later in the UI) and adding to another array (also linked to a .map() function) 2.) showing a custom UI element at the bottom of the screen.
My issue is with testing this particular event handler. It is being called by any of the CustomChip components when they are pressed. The onPress() is passing the 'skill' for which the state changes will be changing their state using.
I would like a jest test to consider these 'covered' so as to achieve code coverage, but I can't seem to design a test to do so. Sources around the net have advised using test renderer to render the component, find the associated button (in my case a chip) and call its onPress() prop and use that to trigger a press. My test UI doesn't seem to change after that, as the desired effect from calling 'reorderSkills' never seems to happen. The snapshot remains the same and the length of the array I'm trying to add this skill to never changes.
If anyone can help me arrange a test for this particular event, I would be grateful. Due to constraints that I can't change, I can't use enzyme or any other testing tool than jest and react-test-renderer.
This is the beginning of my component and the event handler, reorderSkills:
export const SkillsCard = () => {
const [showSnackbar, setShowsnackbar] = useState(false);
const [mySkills, setMyskills] = useState<SkillsParams[]>([
{id: '4', name: 'Tableau'},
]);
const [otherSkills, setOtherskills] = useState(SKILLS);
const reorderSkills = (skill: any) => {
const searchedName = skill.name;
if (mySkills.find((element) => element.name == searchedName)) {
setMyskills(mySkills.filter((item) => item.name !== searchedName));
setOtherskills((arr) => [...arr, {id: skill.id, name: searchedName}]);
} else {
setShowsnackbar(true);
setOtherskills(otherSkills.filter((item) => item.name !== searchedName));
setMyskills((arr) => [...arr, {id: skill.id, name: searchedName}]);
}
};
And this is the jsx return of the component, including the CustomChip custom component that is calling reorderSkills using an onPress() event:
return (
<View style={styles.cardsContainer}>
<View style={styles.mySkillsCard}>
<Headline style={styles.mySkillsHeadline}>My Skills</Headline>
<View style={styles.chipsContainer} testID='mySkillsContainer'>
{mySkills.map((skill) => {
return (
<CustomChip
key={skill.id}
name={skill.name}
selected={null}
icon={<CloseIcon size={16} />}
onPress={() => reorderSkills(skill)}
testID='mySkillsChip'
style={chipstyles.chipSkills}
textStyle={chipstyles.chipTextSkills}
iconLeft={false}
/>
);
})}
</View>
</View>
<View style={styles.suggestedCard}>
<Headline style={styles.mySkillsHeadline}>
Suggested based on your profile
</Headline>
<View style={styles.chipsContainer} testID='suggestedSkillsContainer'>
{otherSkills.map((skill) => {
return (
<CustomChip
key={skill.id}
name={skill.name}
selected={null}
icon={<PlusIcon size={16} />}
onPress={() => reorderSkills(skill)}
testID='suggestedChips'
style={chipstyles.chipSkills}
textStyle={chipstyles.chipTextSkills}
iconLeft={false}
/>
);
})}
</View>
</View>
Finally, this is the test I attempted to implement:
it('should move chips after onPress to suggestedSkills card', () => {
const mySkillsChip = component.root.findAllByProps({
testID: 'mySkillsChip',
})[0];
mySkillsChip.props.onPress();
component.update(<SkillsCard />);
const suggestedChips = component.root.findAllByProps({
testID: 'suggestedChips',
});
expect(suggestedChips).toHaveLength(5);
});
... and this is the code coverage I am lacking:
if (mySkills.find((element) => element.name == searchedName)) {
setMyskills(mySkills.filter((item) => item.name !== searchedName));
setOtherskills((arr) => [...arr, {id: skill.id, name: searchedName}]); // this line here
} else {
setShowsnackbar(true);
setOtherskills(otherSkills.filter((item) => item.name !== searchedName));
setMyskills((arr) => [...arr, {id: skill.id, name: searchedName}]); // ... and this line.
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
