开玩笑测试 JavaScript 代码元素在 setTimeout 完成之前不会出现

Jest testing JavaScript code element does not appear before setTimeout finishes

我有一个 React 组件 ComponentA,一旦渲染,就会启动 setTimeout 函数延迟 500 毫秒,然后渲染正文。我需要测试在这 500 毫秒内没有出现正文,我无法弄清楚如何。

组件A:

function ComponentA() {
  const [showIndicator, setShowIndicator] = useState(false);

  useEffect(()=> {
   setTimeout(()=> setShowIndicator(true), 500);
  }) 

  return (showIndicator && <h1>Hello</h1>);
}

我目前的测试设置是

import {render} from '@testing-library/react'

describe("Test Component A", () => {
  test("it should not show text during first 500 ms", async () => {
     // Point A: rendering time
      const {container, getByText} = render(<ComponentA  />)
     // Point B: before delay
     // Need to assert text is not shown yet before delay
      await sleep(500);
     // Poin C: now text should appear
      expect(getByText('Hello')).toBeInTheDocument()
  });
});

它正在通过,但我不知道如何断言文本在 500 毫秒过去之前没有出现,以及如何知道断言发生的那一刻是在 500 毫秒之前。感谢您的帮助,谢谢

您可以稍等片刻,检查文本是否在文档中:

test("it should not show text during first 500 ms", async () => {
  const {container, getByText} = render(<ComponentA  />)
  await sleep(499);
  expect(getByText('Hello')).not.toBeInTheDocument()
});

我也不确定 sleep 的来源是什么,但万一它造成 真正的 延迟,我建议考虑 fake timers

test("it should not show text during first 500 ms", async () => {
  const {container, getByText} = render(<ComponentA  />)
  jest.advanceTimersByTime(499);
  expect(getByText('Hello')).not.toBeInTheDocument()
});

最后你可以将 2 个测试用例合并在一起(不是因为我认为测试用例的数量很重要,而是因为你实际上测试了与之前显示的延迟相关的相同方面):

test("shows text after 500 ms delay", async () => {
  const {container, getByText} = render(<ComponentA  />)
  jest.advanceTimersByTime(499);
  expect(getByText('Hello')).not.toBeInTheDocument()
  jest.advanceTimersByTime(2);
  expect(getByText('Hello')).toBeInTheDocument()
});