当窗口未定义时,我正try 在自定义钩子中测试此逻辑.

if (typeof window !== "undefined") {
    console.log('inside');
    return true;
}
  console.log('outside');
  return false;
};

从而模拟窗口,如下所示并运行后续测试.

import React from "react";
import { renderHook, act } from "react-hooks-testing-library";

const windowSpy = jest.spyOn(window, "window", "get");

afterEach(() => {
    windowSpy.mockRestore();
});

test("should return false when window is undefined", () => {
    windowSpy.mockImplementation(() => undefined);
    const { result } = renderHook(() => myHook("test"));
    expect(result.current).toBe(false);
});

当我运行这个测试时,窗口没有像预期的那样定义,但我最终得到了以下错误,从react-test-renderer.development.js开始.

TypeError: Cannot read property 'event' of undefined: line 2352

当我在If判断期间查看下面的库时,窗口并不是未定义的.

但当我们到达WindowEvent,Window时.是未定义的.

if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
    // .....
      var windowEvent = window.event; // This is the error. window undefined here.
    // .....
  }
}

可以肯定地说,解决方案不在这个自由党的范围内.但更多的是关于我如何在这里没有问题地嘲笑.

如何编写测试,以便在窗口未定义但不受此库错误影响时进行测试?

全钩子实现,供参考.

import React from "react";
import isWindowDefined from "../isWindowDefined";

export const isWindowDefined = () => window !== undefined;

const useMediaQuery = (query: string): boolean => {
  const getMatches = (query: string): boolean => {
    if (isWindowDefined()) {
      return window.matchMedia(query).matches;
    }
    return false;
  };

  const [matches, setMatches] = React.useState<boolean>(getMatches(query));

  const handleChange = () => {
    setMatches(getMatches(query));
  };

  React.useEffect(() => {
    const matchMedia = window.matchMedia(query);
    handleChange();

    matchMedia.addEventListener("change", handleChange);

    return () => {
      matchMedia.removeEventListener("change", handleChange);
    };
  }, [query]);

  return matches;
};

export default useMediaQuery;

推荐答案

您可以在测试中模拟函数isWindowDefined以返回truefalse.这样,您就不需要在测试中修改window,而这似乎是测试库所依赖的.

例如.

而不是直接在你的钩子里查window

if (typeof window !== "undefined") {
  console.log('inside');
  return true;
}
console.log('outside');
return false;

您可以调用为您执行判断的函数:

import { isWindowDefined } from "path/to/window-util";

// ...

if (isWindowDefined()) {
  console.log('inside');
  return true;
}
console.log('outside');
return false;

然后,在测试中,您可以模拟isWindowDefined()返回truefalse,而不需要与任何真实的window对象交互:

import React from "react";
import { renderHook, act } from "react-hooks-testing-library";
import * as windowUtil from 'path/to/window-util';

// Keep track of the original function implementation so we can reset it after tests
const realIsWindowDefined = windowUtil.isWindowDefined;

afterEach(() => {
    windowUtil.isWindowDefined = realIsWindowDefined;
});

test("should return false when window is undefined", () => {
    windowUtil.isWindowDefined = jest.fn().mockReturnValue(false);
    const { result } = renderHook(() => myHook("test"));
    expect(result.current).toBe(false);
});

然后可以在生产代码中正确实现isWindowDefined来做实际的window判断:

// e.g. defined in module: window-util.js
export function isWindowDefined() {
    return typeof window !== "undefined"
}

Javascript相关问答推荐

验证嵌套 colored颜色 代码的结果

使用Astro和React的动态API

react 路由加载程序行为

确定MutationRecord中removedNodes的索引

警告!合同执行期间遇到错误[执行已恢复](Base Layer 2)

没有输出到带有chrome.Devtools扩展的控制台

如何将连续的十六进制字符串拆分为以空间分隔的十六进制块,每个十六进制块包含32个二元组?

防止用户在selectizeInput中取消 Select 选项

在这种情况下,如何 for each 元素添加id?

MathJax可以导入本地HTML文档使用的JS文件吗?

从Node JS将对象数组中的数据插入Postgres表

我创建了一个创建对象的函数,我希望从该函数创建的对象具有唯一的键.我怎么能做到这一点?

获取';无法解决导入和导入";slick-carousel/slick/slick-theme.css";';错误

回溯替代方式

删除加载页面时不存在的元素(JavaScript)

如何修复使用axios运行TSC index.ts时出现的错误?

Django导入问题,无法导入我的应用程序,但我已在设置中安装了它

如何通过Axios在GraphQL查询中发送数组

AG-GRIDreact 显示布尔值而不是复选框

谷歌饼图3D切片