Как имитировать setTimeOut в модульном тесте Jest?Javascript

Форум по Javascript
Ответить
Anonymous
 Как имитировать setTimeOut в модульном тесте Jest?

Сообщение Anonymous »

В моем приложении мне нужно убедиться, что массив промисов будет выполнен в том порядке, который указан в массиве. Кроме того, приложение должно «ждать» определенное время после каждого выполнения Promise.
Я использую цикл for..of над forEach(). forEach() не будет ожидать каждого промиса отдельно:

Код: Выделить всё

// timerDemo.ts

export async function executeInOrderWithDelay(
fns: (() => Promise)[],
delayMs = 1000,
): Promise {
for (const fn of fns) {
await fn()
await new Promise((r) => setTimeout(r, delayMs))
}
}
Использование этого кода в моем приложении и тестирование его в браузере работает так, как ожидалось.
У меня возникли проблемы в моем Jest-UnitTests, имитирующем setTimeout():

Код: Выделить всё

import { executeInOrderWithDelay } from './TimerDemo'

describe('executeInOrderWithDelay', () => {
afterEach(() => {
jest.useRealTimers()
})

test('executes functions in order with specified delay', async () => {
jest.useFakeTimers()
const calls: number[] = []
const fns = [
jest.fn(() => {
calls.push(1)
return Promise.resolve()
}),
jest.fn(() => {
calls.push(2)
return Promise.resolve()
}),
jest.fn(() => {
calls.push(3)
return Promise.resolve()
}),
]

executeInOrderWithDelay(fns, 1000)

// first should be invoked immediately
expect(fns[0]).toHaveBeenCalledTimes(1)
expect(fns[1]).not.toHaveBeenCalled()

// advance to allow loop to proceed to second
jest.advanceTimersByTime(1000)
expect(fns[1]).toHaveBeenCalledTimes(1)
expect(fns[2]).not.toHaveBeenCalled()

// advance to allow loop to proceed to third
jest.advanceTimersByTime(1000)
expect(fns[2]).toHaveBeenCalledTimes(1)

expect(calls).toEqual([1, 2, 3])
})
})
UT завершается сбоем при первом вызове setTimeout():

Код: Выделить всё

 FAIL  test/TimerDemo.spec.ts
executeInOrderWithDelay
✕ executes functions in order with specified delay (7 ms)

● executeInOrderWithDelay › executes functions in order with specified delay

expect(jest.fn()).toHaveBeenCalledTimes(expected)

Expected number of calls: 1
Received number of calls: 0

32 |     // advance to allow loop to proceed to second
33 |     jest.advanceTimersByTime(1000)
> 34 |     expect(fns[1]).toHaveBeenCalledTimes(1)
|                    ^
35 |     expect(fns[2]).not.toHaveBeenCalled()
36 |
37 |     // advance to allow loop to proceed to third
Как правильно имитировать setTimeout(), чтобы передать UT?


Подробнее здесь: https://stackoverflow.com/questions/798 ... -unit-test
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Javascript»