在运行测试的后续部分之前,如何使用moxios进行反应测试以更新DOM

时间:2019-07-05 14:44:59

标签: reactjs axios react-testing-library moxios

我正在尝试使用jest和react-testing-library为组件编写测试。测试需要等待axios请求后使用useEffect更新状态。我正在使用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子句中,尽管测试通过了,它传递的任何值都表示未正确处理它。

1 个答案:

答案 0 :(得分: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()
    })
  })
})