How to unit test the side effects of react useEffect() hook using Jest and Enzyme

Viewed 769

I am using Jest and Enzyme to test my react component below. I am not able to test the side effects of useEffect() hook. As you see below, useEffect() has a call to back end API and fetch some data, iterative over the data, and setUserProducts() which will be used in its parent component. But the useEffect() is not getting called and not sure how to test its side effects, and because of this, I am not able to test the function getUserProductList() inside this component as well.

I tried with the mount as well but it is the same. The useEffect() is not getting triggered at all. I actually want to spy the fetchUserProductDataFromAPI() and return some mock data and test the side Effects after re-render. Any thoughts on how to test the components in this case?

UserProductComponent.js

const UserProductComponent = props => {
  const {
    userName,
    setUserProducts    
  } = props

  const getUserProductList = (data) => {
  const userProductList = []
  //logic to iterate over the data and get user product data
    return userProductList
  }

  React.useEffect(() => {
    async function pullUserProductDataFromAPI() {
        const { data } = await fetchUserProductDataFromAPI(userName)
        setUserProducts(getUserProductList(data))
    }
    pullUserProductDataFromAPI()
  }, [userName])

  return (
   
      <table>
        <thead>
          <tr>
            <th>product name</th>
          </tr>
        </thead>
        <tbody>
          {
            userProducts !== undefined &&
            userProducts.map((userProduct) => {
              return (<tr>
                <td>{userProduct}</td>
              </tr>)
            })
          }
        </tbody>
      </table>
  )
}

export default UserProductComponent

=========================== UserProductComponent.test.js

describe('UserProductComponent test', () => {
  let props
  let wrapper
  let useEffect

  const mockUseEffect = () => {
    useEffect.mockImplementationOnce(f => f())
  }

  beforeEach(() => {
    props = {
      userName: 'Mark Melon'
      setUserProducts: []
    }

    useEffect = jest.spyOn(React, 'useEffect')
    mockUseEffect()
    mockUseEffect()

    wrapper = shallow(<UserProductComponent {...props} />)
  })

    //test passes successfully
  it('check if it renders compoent UserProductComponents', () => {      
    const header = wrapper.find('table > thead > tr > th')
    expect(UserProductComponent.text()).toBe('product name')
  })

  it('should call setUserProducts()', () => {
     props = {
      userName: 'Mark T'
      setUserProducts: []
    }
    wrapper.setProps({ ...props, ...updatedProps })
    // let useEffect = jest.spyOn(React, 'useEffect')
    // const mockUseEffect = () => {
    //   useEffect.mockImplementation(() => console.log('in use effect'))
    // }
    //const wrapper = shallow(<UserProductComponent {...props} {...updatedProps} />)
    expect(updatedProps.setUserProducts).toHaveBeenCalled() //failing has been called 0 times
  })
})
0 Answers
Related