1

我正在尝试使用 jest 和 react-testing-library 为组件编写测试。测试需要等待 useEffect 更新 axios 请求后的状态。我正在使用 moxios 模拟 api 调用,但我无法让测试等待 moxios 返回,然后再触发单击事件处理程序,该处理程序再次向 api 发送删除请求。测试失败,说明我尝试单击的 DOM 元素尚不存在,因为它仅在 useEffect 请求更新后生成。

我尝试使用 flushEffect 等待,我也尝试将点击包装在初始 moxios 请求中,但两者都不起作用

我已经删除了任何不相关的代码。

这是组件。加载后,它会向 api 发送一个 get 请求,以获取一些好处的 json 响应。BenefitsTable 组件接收好处,并为每个好处生成一个包含删除按钮的表。我正在尝试首先加载好处,然后单击删除按钮。在加载之前不存在删除按钮。

const Benefits = props => {
  const [benefits, setBenefits] = useState([])
  const [editing, setEditing] = useState(false)
  const [editingBenefit, setEditingBenefit] = useState({id: null, name: '', category: ''})

  useEffect(() => {
    axios.get('/api/v1/benefits')
      .then(response => {
        setBenefits(response.data)
      })
  }, [])

  const deleteBenefit = benefit => {
    const id = benefit.id
    axios.delete(`/api/v1/benefits/${id}`)
      .then(response => {
        setBenefits(benefits.filter(benefit => benefit.id !== id))
        warning('Benefit Deleted')
      })
      .catch(error => {
        warning('Benefit could not be deleted. Please try again')
      })
  }

  return(
     <div>
       <Section>
         <BenefitsTable
            benefits={benefits} 
            deleteBenefit={deleteBenefit}
            editBenefit={editBenefit}
          />
       </Section>
     </div>
  )
}

我的测试如下:

it('deletes a benefit when the delete button is clicked', () => {
  const { getByTestId } = render(<Benefits />)
    moxios.wait(() => {
      const request = moxios.requests.mostRecent()
      request.respondWith({
        status: 200,
        response: benefits
      }).then(() => {
        done()
      })
    })
    fireEvent.click(getByTestId('deleteButton1'))
    moxios.wait(() => {
      const request = moxios.requests.mostRecent()
      request.respondWith({
       status: 200,
    }).then(() => {
      expect(document.querySelectorAll('tbody > tr').length).toBe(1)
      done()
    })
  })
})

输出是Unable to find an element by: [data-testid="deleteButton1"],我知道这是因为 axios 请求是异步的,但是我尝试将 fireevent 和后续 axios 请求包装在第一个 axios 请求的 then 子句中,尽管测试通过了,但它以任何值通过,这意味着它是'没有被正确处理。

4

1 回答 1

0

等待元素存在会起作用吗?

it('deletes a benefit when the delete button is clicked', async () => {
  const { getByTestId } = render(<Benefits />)
    moxios.wait(() => {
      const request = moxios.requests.mostRecent()
      request.respondWith({
        status: 200,
        response: benefits
      })
    })
    await waitForElement(getByTestId('deleteButton1'))
    fireEvent.click(getByTestId('deleteButton1'))
    moxios.wait(() => {
      const request = moxios.requests.mostRecent()
      request.respondWith({
       status: 200,
    }).then(() => {
      expect(document.querySelectorAll('tbody > tr').length).toBe(1)
      done()
    })
  })
})
于 2019-07-05T15:03:59.657 回答