Как мне проверить функциональность, доступную только во время существования асинхронного метода, с помощью @test-library / react?

У меня есть компонент React, который позволяет пользователям отправлять потенциально длительные запросы в удаленную службу. Во время выполнения запроса на компоненте отображается кнопка отмены. Я хочу проверить, появляется ли эта кнопка, когда ожидалось, что ее обработчик кликов отменяет предыдущий запрос API и так далее.

Поскольку кнопка присутствует только тогда, когда активен вызов асинхронного API, тесты, которые я написал для этой цели, делают свои утверждения о кнопке в макетной реализации самого асинхронного API. Они не очень элегантны, но я подтвердил, что они действительно становятся красными, как я ожидал, когда я удаляю части производственного кода.

При обновлении @test-library / react с 8.0.1 до 9.3.2, хотя тесты все еще проходят, я теперь несколько раз получаю следующее предупреждение:

console.error node_modules/@testing-library/react/dist/act-compat.js:52
      Warning: You seem to have overlapping act() calls, this is not supported. Be sure to await previous act() calls before making a new one.

Я воспроизвел проблему в следующем CodeSandbox (обязательно выберите вкладку «Тесты» справа, а затем просмотрите сообщения «Консоль» в правом нижнем углу).

 Редактировать sweet-clarke-kq299

В последнем комментарии к этой проблеме GitHub говорится, что я не должен: Мне не нужно беспокоиться о act(), если я использую помощники и функции библиотеки тестирования React (каковыми я и являюсь). Что мне не хватает?


person nickform    schedule 18.11.2019    source источник


Ответы (1)


Поднять вопрос (здесь) против библиотеки response-testing помогло мне прийти к выводу, что лучший подход - не слишком об этом беспокоиться. Автор библиотеки был достаточно любезен, чтобы предложить более простой тестовый образец, просто делая утверждения сразу после действия, которое приводит к переходу компонента в переходное состояние, которое вы пытаетесь протестировать. Например:

fireEvent.click(getByText("Submit")); // <-- action which triggers an async API call

expect(getByText("Fetching answers")).toBeInTheDocument();

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

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

  • не вызывать предупреждения о перекрывающихся вызовах act () в OP
  • может привести к сбою, как ожидалось, если я изменю код, не являющийся тестовым, чтобы нарушить тестируемое поведение
  • пока не показали периодических отказов
  • намного легче читать и понимать

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

person nickform    schedule 27.05.2020