Search code examples
react-nativereact-native-testing-librarynative-testing-library

TouchableOpacity does not show disabled and activeOpacity props


I am trying to test this simple button:

import React, { FC, ReactNode } from 'react';
import { TouchableOpacity, GestureResponderEvent, ViewStyle } from 'react-native';

type Props = {
  style: ViewStyle;
  onPress: (event: GestureResponderEvent) => void;
  disabled?: boolean;
  activeOpacity?: number;
  children: ReactNode;
};

export const Button: FC<Props> = ({
  style,
  onPress,
  disabled,
  activeOpacity,
  children
}) => {
  return (
    <TouchableOpacity
      activeOpacity={ activeOpacity }
      onPress={ onPress }
      style={ style }
      disabled={ disabled }
      testID={ 'button' }
    >
      { children }
    </TouchableOpacity>
  );
};

I use this test file, where I simply render my Button with some props:

import React from 'react';
import { Text, StyleSheet } from 'react-native';
import { render } from '@testing-library/react-native';
import { ReactTestInstance } from 'react-test-renderer';
import { Button } from '../../../src/components/Button';

const styles = StyleSheet.create({
  button: {
    height: 50
  }
});

const onPressMock = jest.fn();

describe('FilterForm', () => {
  it('should render Button with default arguments', () => {
    const { queryByText, debug } = render(
      <Button style={ styles.button } onPress={ onPressMock } disabled activeOpacity={ 0.3 }>
        <Text>{ 'Dummy Test Text' }</Text>
      </Button>
    );

    debug();

    // Not important - just in case you are curious //
    let buttonText = queryByText('Dummy Test Text');
    expect(buttonText).not.toBeNull();
    buttonText = buttonText as ReactTestInstance;
    expect(buttonText.parent?.parent?.props.testID).toEqual('button');
    expect(buttonText.parent?.parent?.props.activeOpacity).toEqual(0.3);
    expect(buttonText.parent?.parent?.props.disabled).toEqual(true);
  });
});

The problem is that I get this tree returned, which does not have disabled or activeOpacity in it:

<View
  accessible={true}
  focusable={true}
  onClick={[Function onClick]}
  onResponderGrant={[Function onResponderGrant]}
  onResponderMove={[Function onResponderMove]}
  onResponderRelease={[Function onResponderRelease]}
  onResponderTerminate={[Function onResponderTerminate]}
  onResponderTerminationRequest={[Function onResponderTerminationRequest]}
  onStartShouldSetResponder={[Function onStartShouldSetResponder]}
  style={
    Object {
      "height": 50,
      "opacity": 1,
    }
  }
  testID="button"
>
  <Text>
    Dummy Test Text
  </Text>
</View>

Because of that my assertions in the test file above fail. How can I test the props of TouchableOpacity then?

Thanks in advance for your time!


Solution

  • I can call disabled prop by using fireEvent(button, 'press'). Disabled button will not call the handler, so I can assert it with expect(handlerMock).not.toBeCalled().

    As to activeOpacity, I guess storybook should be used for visual testing.