Как проверить функцию asyn c в прослушивателе событий с помощью Jest? - PullRequest
2 голосов
/ 29 мая 2020

У меня есть прослушиватель событий, который запускает асинхронную функцию и удаляет некоторые элементы из DOM после завершения:

async function fetchAndRemove() {
  try {
    const response = await fetch('/endpoint-that-returns-json')

    const result = await response.json()
    if (result.status === 'Success') {
      document.querySelector('.my-element').remove()
    }
  } catch (error) {
    console.log(error)
  }
}

function setupListeners () {
  const button = document.querySelector('.my-button')
  button.addEventListener('click', () => {
    fetchAndRemove()
  })
}


setupListeners()

В моем тесте у меня есть:

import fetch from 'jest-fetch-mock';

test('it removes the element after clicking', () => {
  fetch.mockResponse(JSON.stringify({ status: 'Success' }))
  setupListeners()
  document.querySelector('.my-button').click() // .click comes from JSDOM

  expect(document.querySelector('.my-element')).toBeNull()
}

Однако это не работает, потому что я верю в тест, настройка прослушивателя событий и нажатие кнопки запускается синхронно и не дожидается завершения работы asyn c до fini sh.

Я пробовал это идея, но без хороших результатов:

test('it removes the element after clicking', async () => {
  fetch.mockResponse(JSON.stringify({ status: 'Success' }))
  setupListeners()
  await Promise.resolve(document.querySelector('.my-button').click())

  expect(document.querySelector('.my-element')).toBeNull()
}

1 Ответ

1 голос
/ 30 мая 2020

Это неверно, потому что события DOM не связаны с обещаниями, а await Promise.resolve является избыточным:

await Promise.resolve(document.querySelector('.my-button').click())

Он создает задержку в один тик и все.

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

Учитывая, что fetch - шпион, это может быть:

  fetch.mockResponse(JSON.stringify({ status: 'Success' }))
  setupListeners()
  document.querySelector('.my-button').click()
  await fetch.mock.results[0].value; // delay for fetch()
  await null; // another delay for res.json()
  expect(fetch).toBeCalledWith('/endpoint-that-returns-json')
  expect(document.querySelector('.my-element')).toBeNull()
...