Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing onLayout in React Native

I am trying to test a component that uses the onLayout event using @testing-library/react-native, with the component using a setState function through the components props but the function is never called:

expect(jest.fn()).toHaveBeenCalledWith(...expected)

Expected: 100

Number of calls: 0

How can I make this work? What is wrong?

Component:

type Props = {
  children: React.ReactNode
  setHeaderHeight: React.Dispatch<React.SetStateAction<number>>
}

const HeaderSetHeightWrapper = ({ children, setHeaderHeight }: Props) => {
  return (
    <Wrapper
      onLayout={({
        nativeEvent: {
          layout: { height }
        }
      }) => {
        setHeaderHeight(Math.floor(height))
      }}
      testID="header-h"
    >
      {children}
    </Wrapper>
  )
}

const Wrapper = styled.View`
  position: absolute;
  left: 0;
  top: 0;
`

Test:

it('should set the header height on layout', async () => {
  const mockHeight = 100

  const setHeaderHeight = jest.fn()

  const { getByTestId } = render(
    <HeaderSetHeightWrapper setHeaderHeight={setHeaderHeight}>
      <View style={{ width: 100, height: mockHeight }} />
    </HeaderSetHeightWrapper>
  )

  const wrapper = getByTestId('header-h')

  fireEvent(wrapper, new NativeTestEvent('onLayout', { nativeEvent: { layout: { height: mockHeight } } }))

  await wait(() => expect(setHeaderHeight).toHaveBeenCalledWith(mockHeight))
})
like image 986
ejanson Avatar asked Mar 09 '26 08:03

ejanson


1 Answers

You can use fireEvent(element, eventName, data), its documentation is here, and its type is:

type FireEventFunction = (
  element: ReactTestInstance,
  eventName: string,
  ...data: Array<any>
) => void;

So, to fire onLayout, use the layout event name:

// You can use any getBy* or another selector that returns a ReactTestInstance
fireEvent(getByText('Some label'), 'layout', {
  nativeEvent: { layout: { height: 100 } },  // The event data you need
});
like image 200
Rafael Tavares Avatar answered Mar 11 '26 08:03

Rafael Tavares



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!