How to execute onPress on TouchableOpacity react-native using jest and @testing-library/react-native?

4.2k views Asked by At

I have a component called Header that look like this:

import React from 'react'
import {StyleSheet, TouchableOpacity, View, StyleProp, ViewStyle} from 'react-native'
import {Text} from '..'
import Icon from 'react-native-vector-icons/MaterialIcons'
import {theme} from '@app/presentations/utils/styles'
import {useNavigation} from '@react-navigation/core'

interface IHeaderProps {
  title: string
  headerRight?: () => JSX.Element | false | undefined
  onGoBack?: () => void
  hideBackButton?: boolean
  style?: StyleProp<ViewStyle>
}

const Header: React.FC<IHeaderProps> = props => {
  const navigation = useNavigation()

  const goBack = () => {
    props.onGoBack ? props.onGoBack : navigation.goBack()
  }
  return (
    <View style={[styles.container, props.style]}>
      <View style={styles.leftContent}>
        {props?.hideBackButton ? null : (
          <TouchableOpacity onPress={goBack} testID="headerBackButton">
            <Icon name={'chevron-left'} size={22} color={theme.colors.black} />
          </TouchableOpacity>
        )}
      </View>

      <View style={{flex: 1, flexGrow: 10, alignItems: 'center'}}>
        <Text maxLines={2} style={{paddingHorizontal: 8, textAlign: 'center'}} type="semibold">
          {props.title}
        </Text>
      </View>

      <View style={styles.rightContent}>{props.headerRight && props.headerRight()}</View>
    </View>
  )
}

export default Header

Focus on TouchableOpacity, I want to fire the onPress of it using testId, but looks like it won't fire.

  it('Should have correct behavior', () => {
    const goBackFn = jest.fn()
    const props: IHeaderProps = {
      title: 'My Header',
      onGoBack: goBackFn,
    }
    const {component, getByTestId, queryAllByText} = renderComponent(props)
    expect(component).toMatchSnapshot()

    expect(queryAllByText('My Header').length).toBe(1)
    expect(getByTestId('headerBackButton')).toBeTruthy()
    fireEvent.press(getByTestId('headerBackButton'))
    expect(goBackFn).toBeCalled()
  })

The error message was like this

enter image description here

means that my goBack function never executed. I wondering why. Then I check the snapshots of my Header component, it is not show TouchableOpacity but it shows View with onClick function on it

    <View
      accessible={true}
      collapsable={false}
      focusable={true}
      nativeID="animatedComponent"
      onClick={[Function]}
      onResponderGrant={[Function]}
      onResponderMove={[Function]}
      onResponderRelease={[Function]}
      onResponderTerminate={[Function]}
      onResponderTerminationRequest={[Function]}
      onStartShouldSetResponder={[Function]}
      style={
        Object {
          "opacity": 1,
        }
      }
      testID="headerBackButton"
    >

My question is how do I execute onPress on TouchableOpacity ?

1

There are 1 answers

1
Prieyudha Akadita S On

I fixed this. At least there is two problem from my implementation.

  1. On the Header component, I forgot to add parenthesis () on props.onGoBack function. It should be props.onGoBack() not props.onGoBack

  2. I need to add await waitFor(() => { ...wait for my getTestById to be truthy })

enter image description here