如何使用 moxios 进行反应测试以在测试的 运行 之前更新 DOM
How to get react test using moxios to update the DOM before running later part of the test
我正在尝试使用 jest 和 react-testing-library 为组件编写测试。测试需要等待 useEffect 在 axios 请求后更新状态。我正在使用 moxios 来模拟 api 调用,但我无法让测试等待 moxios 到 return,然后它会触发再次向 [=27 发送删除请求的点击事件处理程序=].测试失败表明我尝试单击的 DOM 元素尚不存在,因为它仅在 useEffect 请求更新后生成。
我试过使用 flushEffect 等待,我也试过将点击包装在初始 moxios 请求中,但两者都不起作用
我删除了所有不相关的代码。
这是组件。加载后,它会向 api 发送获取请求,以获取对某些好处的 json 响应。 BenefitsTable 组件接收收益,并为每个收益生成一个 table,其中包括一个删除按钮。我试图先加载福利,然后单击删除按钮。加载前不存在删除按钮。
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 子句中,虽然测试通过,它通过任何值意味着它没有被正确处理。
等待元素出现是否可行?
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()
})
})
})
我正在尝试使用 jest 和 react-testing-library 为组件编写测试。测试需要等待 useEffect 在 axios 请求后更新状态。我正在使用 moxios 来模拟 api 调用,但我无法让测试等待 moxios 到 return,然后它会触发再次向 [=27 发送删除请求的点击事件处理程序=].测试失败表明我尝试单击的 DOM 元素尚不存在,因为它仅在 useEffect 请求更新后生成。
我试过使用 flushEffect 等待,我也试过将点击包装在初始 moxios 请求中,但两者都不起作用
我删除了所有不相关的代码。
这是组件。加载后,它会向 api 发送获取请求,以获取对某些好处的 json 响应。 BenefitsTable 组件接收收益,并为每个收益生成一个 table,其中包括一个删除按钮。我试图先加载福利,然后单击删除按钮。加载前不存在删除按钮。
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 子句中,虽然测试通过,它通过任何值意味着它没有被正确处理。
等待元素出现是否可行?
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()
})
})
})