javascript - 如何修复 vuejs 测试工具中的 jest window.alert 或 null 错误?

标签 javascript unit-testing vue.js jestjs

我想测试我的 vue 组件,但是我遇到了一些该死的疯狂错误,我使用 jsdom 做了人们喜欢的事情,没有修复它,并且不断显示这些错误:

  console.error node_modules/jest-environment-jsdom/node_modules/jsdom/lib/jsdom/virtual-console.js:29
      Error: Not implemented: window.alert

 [Vue warn]: Error in mounted hook: "TypeError: Cannot read property 'addEventListener' of null"

我有一个 Header 组件,其安装位置是:

    methods: {
.
.
.
      addEventHandler(...args: any) {
        addEventHandler(...args);
      }
    },
mounted() {
  this.addEventHandler('.dej_search', 'enter', '.dej_suggestion .active-item', this.enterSection);
  //@ts-ignore
  this.addEventHandler('', 'ctrl+f||f3', 'GeneralSearch', id => document.getElementById(id).focus());
}

事件处理程序代码如下:

//addEventHandler.js:
import Vue from "vue"
import {keyboardCodes} from "@/utils/keyboardCodes";


const {enter, f, f3} = keyboardCodes;
export const addEventHandler = (domSelector = '',
                                event = '',
                                data = '',
                                eventHandler = (item) => {
                                }
) => {
  let dom = domSelector !== '' ? document.querySelector(domSelector) : window;
  switch (event) {
    case "enter":
      dom.addEventListener("keypress", (e) => {
        let key = e.which || e.keyCode || 0;
        if (key === enter) {
          eventHandler(data);
          e.preventDefault();
        }
      });
      break;
    case "ctrl+f||f3":
      dom.addEventListener("keydown", (e) => {
        let key = e.which || e.keyCode || 0;
        if (key === f3 || (e.ctrlKey && key === f)) {
          eventHandler(data);
          e.preventDefault();
        }
      });
      break;
    default:
      console.log("event ....");
      break;
  }
};

正如你所看到的,我也使用了 jsdom,但我没有解决问题,而且我真的很困惑我应该如何解决这些问题并在 jest 框架中进行一些单元测试而不痛苦。

//header.test.js

import {mount, shallowMount} from "@vue/test-utils";
import Header from "../../../src/views/pages/Panel/Header";
import {JSDOM}  from "jsdom";

const dom = new JSDOM()
document = dom.window.document;
window = dom.window;
window.alert = jest.fn();

describe("mount",()=>{
  const wrapper = shallowMount(Header);
  console.log(wrapper.vm);
  console.log(wrapper.element);
});

我们应该如何消除这些错误?

......

更新

我可以修复 window.alert 错误。由于 jest 不支持或以其他方式无法在 cli 中测试 ui,因此无法测试警报等某些功能或很难测试 https://jestjs.io/docs/en/tutorial-jquery 提到的功能。 因此,为了解决 window.alert 问题,我们可以添加一个相同的实现或空的实现,以防止测试失败:

window.alert = () => {};  // provide an empty implementation for window.alert
// or 
window.alert = (text) => {console.log(text)};  // provide an non-empty implementation for window.alert

但我真的不知道如何模拟我在 addEventHandler.js 中使用的 document.getElementById 来防止“addEventListener”为 null 时出现此类错误。 有什么好的解决办法吗?

最佳答案

window.alert 和其他几个特定于浏览器的副作用需要手动进行 stub 。最好使用 Jest 来完成此操作,以便可以跟踪并清除 spy :

jest.spyOn(window, 'alert').mockReturnValue();

然后可以断言对 window.alert 的调用。

如果 JSDOM 自动对它进行 stub ,则弊大于利。这很少会成为问题,因为 alert 对 UI/UX 不友好,并且在生产代码中并不常见。

TypeError: Cannot read property 'addEventListener' of null

表示该元素不存在。这可能是由于组件安装较浅且未完全渲染所致,这通常是单元测试的首选策略。

可以模拟 addEventListener 方法或具有 addEventListener 的模块来阻止对 DOM 的访问:

jest.mock('.../addEventListener', () => ({ addEventListener: jest.fn() }));

addEventListener 的调用也可以被断言。

关于javascript - 如何修复 vuejs 测试工具中的 jest window.alert 或 null 错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60152275/

相关文章:

javascript - VueJS : Replace/Update Array

html - Vue.js:无法使用 CSS 媒体查询隐藏带有侧边栏的 div

javascript - weex.js - 如何将循环变量传递到事件处理程序中

javascript - 如何在HTML中执行Electron js命令?

javascript - 两次更改 div 样式,打开和关闭问题。

c# - 自定义数据驱动的 MSTest

iphone - SenTesting 在第一次 STAsert 失败后停止测试

javascript - 多个 jQuery 选择器,ID 以特定字符开头

unit-testing - 良好的边境测试

javascript - 使用 v-model 改变 prop 的属性是不好的做法吗?