我正在使用 Jest 和 Enzyme 来测试下面的 react 组件。我无法测试 useEffect()
钩子的副作用。正如您在下面看到的,useEffect()
调用了后端 API 并获取一些数据,对数据进行迭代,以及将在其父组件中使用的 setUserProducts()
。
但是 useEffect()
没有被调用,也不确定如何测试它的副作用,因此,我也无法测试此组件中的 getUserProductList()
函数。
我也尝试过使用 mount
但结果是一样的。 useEffect() 根本没有被触发。
我实际上想监视 fetchUserProductDataFromAPI()
并返回一些模拟数据并在重新渲染后测试副作用。
关于如何在这种情况下测试组件的任何想法?
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
})
})