【问题标题】:How to get react test using moxios to update the DOM before running later part of the test如何在运行测试的后期部分之前使用 moxios 进行反应测试以更新 DOM
【发布时间】:2019-07-05 14:44:59
【问题描述】:

我正在尝试使用 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 子句中,虽然测试通过了,但它通过了任何值都意味着它没有被正确处理。

【问题讨论】:

    标签: reactjs axios react-testing-library moxios


    【解决方案1】:

    等待元素出现会起作用吗?

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

    【讨论】:

    • 谢谢乔治。看起来可行,但由于某种原因,第二个 axios 请求没有触发。我将不得不深入挖掘。感谢您的回复
    • 没问题。确保您只调用一次done
    • 仅供参考,我使用不同的方法来测试异步代码:polvara.me/posts/how-to-test-asynchronous-methods 对我来说比moxios 更容易。也许它可以帮助你的情况
    • 感谢您的帮助。我去看看文章
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 2018-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多