如何使用 Jest 和 Enzyme 单元测试 react useEffect() 钩子的副作用

时间:2021-02-21 01:04:17

标签: javascript reactjs jestjs enzyme

我正在使用 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
  })
})

0 个答案:

没有答案