首页 > 解决方案 > 如何修复 vuejs 测试工具中的 jest window.alert 或 null 错误?

问题描述

我想测试我的 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/中提到的教程-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的错误“。有什么好的解决方案吗?

标签: javascriptunit-testingvue.jsjestjs

解决方案


window.alert以及其他几个特定于浏览器的副作用需要手动存根。这最好用 Jest 来完成,这样可以跟踪和清理间谍:

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

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

如果 JSDOM 自动存根,这将弊大于利。这很少是一个问题,因为alert它对 UI/UX 不友好并且在生产代码中不常见。

TypeError:无法读取 null 的属性“addEventListener”

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

可以模拟addEventListener方法或模块addEventListener以防止访问 DOM:

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

addEventListener也可以断言调用。


推荐阅读