Почему мой асинхронный тест Jest не дает сбой, когда должен?

У меня есть несколько асинхронных действий, которые мне нужно протестировать с помощью Jest. Мой тест в настоящее время проходит, когда он должен потерпеть неудачу.

describe('Asynchronous Code', () => {
  it('should execute promise', () => {
    console.log(1);
    someFunctionThatReturnsAPromise()
      .then(() => {
        console.log(2);
        expect(true).toBeFalsy();
        console.log(3);
      });
    console.log(4);
  });
});

Когда я запускаю npm test, я получаю следующий вывод:

PASS  __tests__/Async.test.js
 ● Console

   console.log __tests__/Async.test.js:3
     1
   console.log static-content-test/react/actions/DashboardActions.test.js:6
     2
   console.log static-content-test/react/actions/DashboardActions.test.js:10
     4

Как видите, тест проходит, но console.log(3) никогда не выполняется, потому что true не является ложным, и ожидание не выполняется.

Как я могу заставить Jest распознавать мои ожидания внутри асинхронных обратных вызовов?


person Luke    schedule 31.10.2016    source источник


Ответы (3)


При тестировании асинхронного кода вам нужно вернуть промис из теста. Измените тело теста на:

return someFunctionThatReturnsAPromise()
  .then(() => {
    expect(true).toBeFalsy();
  });

При этом тест терпит неудачу, как и ожидалось:

FAIL  __tests__/Async.test.js
 ● Asynchronous Code › should execute promise

   expect(received).toBeFalsy()

   Expected value to be falsy, instead received
     true

Это шаблон, который Facebook использует для тестирования асинхронного кода с шутка.

person Luke    schedule 31.10.2016
comment
Есть ли способ протестировать несколько таких промисов в одном тесте в Jest или мне нужно сделать один тест на промис? (async/await в этом случае не работает) - person Sergej; 27.01.2018
comment
@Sergej Это зависит от нескольких разных вещей. Если вы пытаетесь проверить взаимосвязь между промисами, вы можете используйте Promise.all. Однако, если они различны, вы, вероятно, захотите их в отдельных тестах. - person Luke; 29.01.2018

Кроме того, вы можете следовать шаблону done, как описано здесь:

it('should execute promise', (done) => {
  someFunctionThatReturnsAPromise()
    .then(() => {
      expect(true).toBeFalsy();
      done();
    });
});

Это будет работать с Jest, но чаще используется с Jasmine и Mocha.

person Luke    schedule 31.10.2016

Вот альтернативное решение.

Jest будет завершен, как только достигнет конца контекста. Таким образом, вам нужно вернуть обещание из обратного вызова, чтобы сообщить ему, чтобы дождаться, пока обещание будет разрешено и протестировано.

Допустим, есть обещание

const promise=fetch("blah.com/api")

test("should return valid data",()=>{
   return expect(promise).resolves.toBeTruthy() 
})

.resolves ждет разрешения promise, и вы применяете соответствующий matchers по своему желанию.

А также вы можете использовать .rejects при проверке ошибок.

person varaprasadh    schedule 10.07.2020