testing-library/native-testing-library

fireEvent.layout doesn't trigger onLayout for TouchableOpacity

technotariat opened this issue · 2 comments

  • react-native or expo: Expo
  • native-testing-library version: 5.0.3
  • jest-preset: @testing-library/react-native
  • react-native version: Expo 38 / RN 0.62
  • node version: 14

Relevant code or config:

    import { act, render, fireEvent, wait } from '@testing-library/react-native';

    it('Passes with View', async () => {
        const mockOnLayout = jest.fn();
        function MyComponent() {
            return (
                <View onLayout={(e) => mockOnLayout(e)} testID='my-view'>
                    <View style={{ height: 200, width: 200}} />
                </View>
            )
        }
        const { getByTestId } = render(<MyComponent />);
        const view = getByTestId('my-view');
        act(() => {
            fireEvent.layout(view, {
                nativeEvent: {
                    layout: {
                        width: 300,
                    },
                },
            });
        });
        await wait(() => expect(mockOnLayout).toHaveBeenCalled());
    });
    it('Fails with TouchableOpacity', async () => {
        const mockOnLayout = jest.fn();
        function MyComponent() {
            return (
                <TouchableOpacity onLayout={(e) => mockOnLayout(e)} testID='my-view'>
                    <View style={{ height: 200, width: 200}} />
                </TouchableOpacity>
            )
        }
        const { getByTestId } = render(<MyComponent />);
        const view = getByTestId('my-view');
        act(() => {
            fireEvent.layout(view, {
                nativeEvent: {
                    layout: {
                        width: 300,
                    },
                },
            });
        });
        await wait(() => expect(mockOnLayout).toHaveBeenCalled());
    });

What you did:

Tried to test the onLayout functionality of a component that uses TouchableOpacity.

What happened:

Mocked onLayout handler was never called.

I had followed https://stackoverflow.com/questions/57961440/testing-onlayout-in-react-native/61774123#61774123 which suggested that it should work and on testing a View based component like in the example it worked, however on changing the View to TouchableOpacity it no longer worked.

Reproduction:

See attached test cases.

Problem description:

onLayout is a prop supported by TouchableOpacity so it'd be good to be able to verify that my component called it's onLayout handler that I pass to it when a layout event is triggered.

I've also noticed that when inspecting the view objects in both examples that the View based object has it's type and elementType properties set to View whereas the TouchableOpacity has both properties set to ''.

Not sure if that will help figure out what's happening or not

Apparently this library is going to be deprecated, but in the meantime this should fix the firing of that handler in your tests:

#136 (comment)