'How to test useEffect call of child component using jest and react-native testing library?

I use react-native and react-native testing library with jest. The component structure is as follows.

function doSomething(x) {
    return x.map(i => i)
}

const ComponentA = (props) => {

    const data = React.useMemo(() => {
       return doSomething(props.data)
    }, [props.data])

    return <ComponentB data={data} />
}

const ComponentB = (props) => {
    React.useEffect(() => {
        // do something
    }, [props.data])

   return (...)
}

I want to test that the useEffect in ComponentB is called only once if props.data passed to ComponentA does not change. The use of useMemo fixed a bug which caused the useEffect in ComponentB to be called on every render of ComponentA since map returns a new array on each call. Thus, without making it stable, the useEffect will be called on every render.

I am unsure how to test the call of useEffect in ComponentB on render of ComponentA.

Here is what I have so far.

describe("Test component", () => {
  const useEffect = jest.spyOn(React, "useEffect")

  it("test component b useEffect", () => {
    const  data = []
    const component = <ComponentA data={data} />
    const { rerender } = render(component)

    expect(useEffect).toHaveBeenCalledTimes(1)

    void act(() => {
      rerender(component)
    })

    // data props has not changed
    expect(useEffect).toHaveBeenCalledTimes(1)

    ...
  })
})

This is obviously wrong and incomplete. How do I correctly check the calls of useEffect in ComponentB?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source