我有一个运行异步函数的事件侦听器,并在完成后从DOM中删除了一些元素:
async function fetchAndRemove() {
try {
const response = await fetch('/endpoint-that-returns-json')
const result = await response.json()
if (result.status === 'Success') {
document.querySelector('.my-element').remove()
}
} catch (error) {
console.log(error)
}
}
function setupListeners () {
const button = document.querySelector('.my-button')
button.addEventListener('click', () => {
fetchAndRemove()
})
}
setupListeners()
在我的测试中,我有:
import fetch from 'jest-fetch-mock';
test('it removes the element after clicking', () => {
fetch.mockResponse(JSON.stringify({ status: 'Success' }))
setupListeners()
document.querySelector('.my-button').click() // .click comes from JSDOM
expect(document.querySelector('.my-element')).toBeNull()
}
但是这不起作用,因为我相信测试会成功进行,设置事件侦听器并单击按钮会同步运行,并且不会等待异步工作完成。
我尝试了这个主意,但没有好结果:
test('it removes the element after clicking', async () => {
fetch.mockResponse(JSON.stringify({ status: 'Success' }))
setupListeners()
await Promise.resolve(document.querySelector('.my-button').click())
expect(document.querySelector('.my-element')).toBeNull()
}
答案 0 :(得分:1)
这是错误的,因为DOM事件不涉及承诺,并且await Promise.resolve
是多余的:
await Promise.resolve(document.querySelector('.my-button').click())
它会产生一按延迟,仅此而已。
由于fetchAndRemove
是在其定义的同一模块中引用的,因此无法进行侦查,因此fetch
Promise应该被链接起来以保持正确的执行顺序。
考虑到fetch
是间谍,它可以是:
fetch.mockResponse(JSON.stringify({ status: 'Success' }))
setupListeners()
document.querySelector('.my-button').click()
await fetch.mock.results[0].value; // delay for fetch()
await null; // another delay for res.json()
expect(fetch).toBeCalledWith('/endpoint-that-returns-json')
expect(document.querySelector('.my-element')).toBeNull()