I'm building a React Native app that lists live music gigs. The user can toggle between showing the current day's gigs or the current week's gigs.If the user presses the 'Gigs Today' button, the state variable showWeek
is set to false; if the 'Gigs This Week' button is pressed, showWeek
is set to true.
The components GigsByDay
is rendered when showWeek
is set to false; GigsByWeek
is rendered when it is true:
Parent component ListByDay.tsx
type ListScreenNavigationProp = listProps["navigation"];interface Props { navigation: ListScreenNavigationProp;}const ListByDay: FC<Props> = ({ navigation }): JSX.Element => { const [showWeek, setShowByWeek] = useState<boolean>(false); const currentDateMs:number = Date.now() const gigs = useGigs(); const gigsToday = getGigsToday(gigs, currentDateMs); const gigsThisWeek = getGigsThisWeek(gigs, currentDateMs); const gigsToRender = showWeek ? (<GigsByWeek gigsThisWeek_grouped={gigsThisWeek} navigation={navigation} /> ) : (<GigsByDay navigation={navigation} gigsFromSelectedDate={gigsToday} /> ); return (<View><View style={styles.buttonContainer}><TouchableOpacity onPress={() => setShowByWeek(false)} style={styles.touchable} testID = 'gigsTodayButton'><Text style={showWeek ? null : styles.selected}>Gigs today</Text></TouchableOpacity><TouchableOpacity onPress={() => setShowByWeek(true)} style={styles.touchable}><Text testID="header" style={showWeek ? styles.selected : null}> Gigs this week</Text></TouchableOpacity></View> {gigsToRender}</View> );};
I want to test that this toggle is working correctly, using React Native Testing Library and Jest.
My approach is to i) isolate the GigsByDay
component, ii) trigger a press event for the 'Gigs Today' button, and then iii) test if either the state is false
, or that the GigsByDay
component has been rendered/is visible to the user.
My question is this - how do test a state change/if a component has been rendered? And are either of these ways actually the right approach?
Here's the test I've written so far, which has failed:
test("that 'showWeek' state is switched to false when 'Gigs Today' pressed", () => { render(<ListByDay />); const gigsToday = screen.getByTestId("gigs-today") fireEvent.press(screen.getByTestId("gigsTodayButton")) expect(getByTestId("gigs-today").state.showWeek).toBe(false) // what should be done here?})
Here's the GigsByDay component:
import { FC } from 'react';import { FlatList,TouchableOpacity,StyleSheet,View,Image,Text } from 'react-native'import { listProps } from '../routes/homeStack';import { GigObject } from '../routes/homeStack';type ListScreenNavigationProp = listProps['navigation']interface Props { gigsFromSelectedDate: GigObject[], navigation: ListScreenNavigationProp}const GigsByDay:FC<Props> = ({ gigsFromSelectedDate, navigation }):JSX.Element => (<FlatList testID = 'gigs-today' data={gigsFromSelectedDate} keyExtractor={item => item.id} renderItem={({ item }) => (<TouchableOpacity style={styles.gigCard} onPress={() => navigation.navigate('GigDetails', { venue: item.venue, gigName: item.gigName, blurb: item.blurb, isFree: item.isFree, image: item.image, genre: item.genre, dateAndTime: {...item.dateAndTime}, tickets: item.tickets, id:item.id }) }><View style={styles.gigCard_items}><Image style={styles.gigCard_items_img} source={require('../assets/Icon_Gold_48x48.png')} /><View><Text style={styles.gigCard_header}>{item.gigName}</Text><Text style={styles.gigCard_details}>{item.venue}</Text></View></View></TouchableOpacity> )} />)