Шутка не подводит при использовании «разрешает»

#javascript #reactjs #promise #jestjs

#javascript #reactjs #обещание #jestjs

Вопрос:

Я написал функцию, которую пытаюсь протестировать с помощью jest:

 asyncUpperCase(value: string): Promise<string> {
  return new Promise(function(resolve, reject) {
    setTimeout(() => {
      return resolve(value.toUpperCase())
    }, 1000);
  })
}
 

Он получает строку и превращает ее в строку верхнего регистра (асинхронно).

Я должен проверить:

 it('upperCase with promise and then', () => {
  return myAsync.asyncUpperCase('hello world').then(value => {
    expect(value).toBe('HELLO WORLD');
  })
})

it('upperCase with promise and resolve', () => {
  const promise = myAsync.asyncUpperCase('hello world');
  expect(promise).resolves.toBe('HELLO WORLD');
})
 

Первый тест работает правильно. Но второй тест никогда не терпит неудачу. Поэтому, если я изменю ожидаемую строку на ABC нее, она все равно завершится успешно. Почему и как мне resolves правильно использовать?

Ответ №1:

Обещание является асинхронным и требует времени для разрешения, нет никакого способа, как resolves может не пройти синхронный тест. Без привязки к тесту это приведет к необработанному отклонению, если тестовый прогон достаточно длинный.

Это должно быть:

 await expect(promise).resolves.toBe('HELLO WORLD');
 

Ответ №2:

Jest предоставляет 3 варианта для правильной обработки документации по асинхронным тестам

Возврат обещания

 it('upperCase with promise and resolve', () => {
  const promise = myAsync.asyncUpperCase('hello world');
  return expect(promise).resolves.toBe('HELLO WORLD');
})
 

Использование async / await

Это то же самое, что и асинхронная функция, которая вернет Promise<void>

 it('upperCase with promise and resolve', async () => {
  const promise = myAsync.asyncUpperCase('hello world');
  expect(await promise).toBe('HELLO WORLD');
})
 

Использование обратного вызова

 it('upperCase with promise and resolve', (done) => {
  const promise = myAsync.asyncUpperCase('hello world');
  promise
        .then(result => expect(promise).toBe('HELLO WORLD'))
        .then(done);
})
 

также вы можете взглянуть на предварительные таймеры по времени