как протестировать встроенный асинхронный вызов

#javascript #unit-testing #jestjs

#javascript #модульное тестирование #jestjs шутки #jestjs

Вопрос:

Я тестирую функцию, parent() которая вызывает функцию slomo() , которая возвращает обещание. Я хочу проверить, выполняется ли код внутри .then() .

 function slomo() {
  return new Promise(function (resolve, reject) {
    resolve('good')
    reject('bad')
  })
}

child = jest.fn()

function parent() {
  slomo()
    .then((result) => {
      child()
    })
}

// TEST

it('runs child', () => {
  parent()
  expect(child).toHaveBeenCalledTimes(1)
})
  

в результате получается:

Ожидаемая фиктивная функция вызывалась один раз, но она вызывалась ноль раз.

Я подтвердил, что дочерняя функция вызывается через console.log , но она регистрируется ПОСЛЕ завершения теста.
Я пробовал передавать и вызывать done внутри теста, но это не исправило проблему.
Может быть, приведенный выше код является антишаблоном и его нужно переписать, чтобы его можно было протестировать?

Я очень ценю любую помощь, которую вы можете мне оказать!

Ответ №1:

Вы правильно нашли корень проблемы, этот тест завершается раньше, чем асинхронный код, поэтому тест должен правильно отслеживать асинхронность. Но, похоже, вы потеряли обещание, потому что вы его не возвращаете, поэтому:

 function parent() {
  return slomo() // <<<--- add return 
    .then((result) => {
      child()
    })
}
  

Далее вы просто можете добавить done :

 it('runs child', (done) => { // <<<< --- add done
  parent().then(() => {
    expect(child).toHaveBeenCalledTimes(1)
    done(); // <<<< -- done should be called after all
  })
});
  

или просто верните обещание:

 it('runs child', () => {
  return parent().then(() => {  // <<<--- return
    expect(child).toHaveBeenCalledTimes(1);
  })
})
  

Надеюсь, это поможет.

Комментарии:

1. Алекс — потрясающий цветок! хотя ответ done не решил проблему для меня (не уверен, почему), решение return сработало отлично. спасибо, что нашли время помочь мне с этой проблемой. счет

2. что, если я не хочу возвращать функцию? существуют более сложные случаи, когда возвращаемое значение является не slomo функцией, а чем-то другим, и по соображениям производительности я просто хочу запустить slomo функцию, но не ждать ее?

3. @Ella похоже, у вас уже есть решение для такого случая, не стесняйтесь публиковать свой ответ, тогда я поддержу его :). Не могли бы вы также поделиться, какова прибыль от производительности в только что удаленном return заявлении?