【问题标题】:React Testing Library - Failing to test Window Resize React HookReact 测试库 - 无法测试 Window Resize React Hook
【发布时间】:2021-01-12 08:25:47
【问题描述】:

我创建了一个自定义 React Hook,用于在窗口调整大小时获取视口宽度和高度(事件被去抖动)。钩子工作正常,但我一直无法找到使用 React 测试库进行测试的方法(我一直遇到错误)。

我在 CodeSandbox 中重新创建了应用程序(连同测试)以尝试调试,但在测试时遇到了不同的错误。

有时我会得到:

Failed to execute 'dispatchEvent' on 'EventTarget': parameter 1 is not of type 'Event'.`

但一般的故障是从钩子中获取的数据似乎没有返回。

expect(received).toBe(expected) // Object.is equality

Expected: 500
Received: undefined

这可能是我在 React 测试库中缺少的东西。

任何帮助解决问题的人都将非常感激!

在这里演示应用程序/测试:

https://codesandbox.io/s/useviewportsize-4l7gb?file=/src/use-viewport-size.test.tsx

============

解决方案

感谢@tmhao2005,问题似乎在于从document而不是window获取调整大小值:

  setViewportSize({
    width: window.innerWidth, //document.documentElement.clientWidth - doesn't work
    height: window.innerHeight //document.documentElement.clientHeight - doesn't work
  });

在应用程序中获取clientWidth/Height 似乎很好,但在 React 测试库测试中失败。

我选择了 client 大小,因为我认为这不包括 scollbar 宽度。

【问题讨论】:

  • 除了测试失败之外,似乎没有发生您上面提到的错误?
  • 是的,测试失败是我正在努力解决的问题。如果您单击测试失败,它会显示“无法在 'EventTarget' 上执行 'dispatchEvent':参数 1 不是 'Event' 类型。” - 啊,等一下,刷新页面,现在错误消失了 - 但是测试仍然失败。
  • 不,我看不到这样的东西。这是我看到的loom.com/share/840989b580d7416c8265736e2c92e0fe
  • 感谢@tmhao2005 的视频 - 是的,这可能是codeandbox 的一个奇怪问题。但主要是我正在寻找如何测试这个钩子的帮助(我已经更新了上面的问题)。
  • 我给你一个建议作为答案。检查我的内联评论以确保您正确跟进

标签: reactjs react-testing-library


【解决方案1】:

我认为您必须进行一些更改才能使您的测试再次运行:

  • 您还没有等待去抖动功能工作,这是主要问题。因此,您可以使用模拟计时器或等到您的 debounce 函数被调用。
// Make your test as `async` in case of wanting to wait
test("should return new values on window resize", async () => {
  // If you go for mocking timer, uncomment this & below advance the timer 
  // jest.useFakeTimers();
  const { result } = renderHook(() => useViewportSize());

  act(() => {
    window.resizeTo(500, 500);
    //fireEvent(window, new Event("resize"));
  });

  // jest.advanceTimersByTime(251) // you can also use this way
  await mockDelay(debounceDelay); // `await` 300ms to make sure the function callback run

  expect(result.current.width).toBe(500);
  expect(result.current.height).toBe(500);
});

  • 您可以改用模拟值来优化您的实现代码:
const debouncedHandleResize = debounce(() => {
  setViewportSize({
    // using your mock values
    width: window.innerWidth,
    height: window.innerHeight
  });
}, debounceTime);

PS:我还根据异步方式编辑了您的代码框:https://codesandbox.io/s/useviewportsize-forked-pvnc1?file=/src/use-viewport-size.test.tsx

【讨论】:

  • 谢谢@tmhao2005 - 我已经设置了 async/await(使用 mockDelay)并查看这是否是问题的根源,但似乎归结为:setViewportSize({ width: window .innerWidth, //document.documentElement.clientWidth - 不起作用高度:window.innerHeight //document.documentElement.clientHeight - 不起作用 });问题似乎是 document.documentElement.clientX 在测试中没有响应(但在应用程序本身中很好)
  • 是的,它看起来在模拟的情况下不起作用。但是最好是模拟计时器,因为它更有意义并且速度更快:)
猜你喜欢
  • 2020-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-09
  • 1970-01-01
  • 2021-01-24
  • 2020-06-09
  • 2021-02-20
相关资源
最近更新 更多