我有一个特殊的设置。 API以每秒的超时调用服务器,响应数据为“已排队”或“已完成”。当数据排队时,我使用axios重复API调用。如果已完成,则清除超时并重新加载页面(由于服务器,该页面将具有更新的HTML)。
我使用Jest进行测试,但出现错误
Timeout - Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout.
Timeout - Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout.Error:
当我将callback()调用添加到else if块的“ complete”部分时,它消失了
else if ('complete'.includes(worker_response.data.status)) {
clearTimeout(t)
window.location.reload()
}
代码在下面
const $ = require('jquery')
const axios = require('axios')
let t
function waitForWorker({ poll_interval = 1000, callback = null }) {
if (!$('.worker-waiter').length) {
callback && callback()
return
}
const worker_id = $(".worker-waiter").data('worker-id')
const working_statuses = ['queued', 'working']
axios.get(`/v1/workers/${worker_id}`).then(worker_response => {
if(working_statuses.includes(worker_response.data.status)) {
timer(poll_interval, callback)
} else if ('complete'.includes(worker_response.data.status)) {
clearTimeout(t)
window.location.reload()
}
else {
window.location.reload()
callback && callback()
}
})
}
function timer(poll_interval, callback) {
t = setTimeout(
() => waitForWorker({
poll_interval,
callback
}),
poll_interval
)
}
module.exports = waitForWorker
if (process.env.NODE_ENV !== 'test') $(waitForWorker)
测试如下:
import axios from 'axios'
jest.mock('axios')
beforeAll(() => {
Object.defineProperty(window, 'location', {
value: { reload: jest.fn() }
})
});
beforeEach(() => jest.resetAllMocks() )
describe('worker is complete after 2 API calls', () => {
const worker_id = Math.random().toString(36).slice(-5) // random string
beforeEach(() => {
axios.get
.mockResolvedValueOnce({ data: { status: 'working' } })
.mockResolvedValueOnce({ data: { status: 'complete' } })
document.body.innerHTML = `<div class="worker-waiter" data-worker-id="${worker_id}"></div>`
})
it('polls the correct endpoint once a', done => {
require('worker_waiter')({
poll_interval: 0,
callback: () => {
const endpoint = `/v1/workers/${worker_id}`
expect(axios.get.mock.calls).toEqual([
[endpoint]
])
done()
}
})
})
it('completes the call', done => {
require('worker_waiter')({
poll_interval: 0,
callback: () => {
expect(axios.get.mock.calls).toEqual([
[endpoint]
])
done()
}
}
)
})
it('reloads the page', done => {
require('worker_waiter')({
poll_interval: 0,
callback: () => {
expect(window.location.reload).toBeCalled()
done()
}
})
})
})
describe('worker is complete after only 1 API call', () => {
const worker_id = Math.random().toString(36).slice(-5) // random string
beforeEach(() => {
axios.get.mockResolvedValueOnce({ data: { status: 'complete' } })
document.body.innerHTML = `<div class="worker-waiter" data-worker-id="${worker_id}"></div>`
})
it('polls the correct endpoint once', done => {
require('worker_waiter')({
poll_interval: 0,
callback: () => {
const endpoint = `/v1/workers/${worker_id}`
expect(axios.get.mock.calls).toEqual([[endpoint]])
done()
}
})
})
it('reloads the page', done => {
require('worker_waiter')({
poll_interval: 0,
callback: () => {
expect(window.location.reload).toBeCalled()
done()
}
})
})
})
describe('page does not have any worker-waiter component', () => {
beforeEach(() => {
axios.get.mockImplementation()
document.body.innerHTML = '<div></div>'
})
it('does not poll the endpoint', done => {
require('worker_waiter')({
callback: () => {
expect(axios.get.mock.calls.length).toBe(0)
done()
}
})
})
it('does not reloads the page', done => {
require('worker_waiter')({
poll_interval: 0,
callback: () => {
expect(window.location.reload).not.toBeCalled()
done()
}
})
})
})