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
})
})