如何使用 JSDom 对 Jest 中的自定义元素执行单元测试

How to perform unit tests for custom elements in Jest using JSDom

我知道有人在 number of occasions, though the environment has changed since those questions where asked: notably, JSDom now supports custom elements 上问过这个问题。

这些其他问题围绕着寻找替代方案(例如使用 ),因为当时 JSDom 不支持自定义元素。不过现在JSDom确实支持自定义元素了,请问有没有人有资料可以解决下面的错误?

TypeError: Class constructor HTMLElement cannot be invoked without 'new'

  1 | export default class Foo extends HTMLElement {
  2 |   constructor() {
> 3 |     super();
    |     ^
  4 | 
  5 |     this._clicker = 2;
  6 |   }

at new Foo (__tests__/fooclass.js:3:5)     
at Object.<anonymous> (__tests__/fooclass.test.js:7:13)

当前设置:

参考存储库可用here(现已修复):

自定义元素示例

class Foo extends HTMLElement {
  constructor() {
    super();

    this._clicker = 2;
  }

  connectedCallback() {
    this.textContent = 'My Foo Bar Element';
  }

  get testCallback() {
    return 'hello world!';
  }

  set clicker(num) {
    this._clicker = Number(num);
  }

  get clicker() {
    return this._clicker;
  }
}

packages.json

{
  "scripts": {
    "test": "jest --env=jest-environment-jsdom-sixteen"
  },
  "jest": {
    "verbose": true
  },
  "devDependencies": {
    "@babel/preset-env": "^7.8.4",
    "babel-plugin-transform-builtin-classes": "^0.6.1",
    "jest": "^25.1.0",
    "jest-environment-jsdom-sixteen": "^1.0.2"
  }
}

.babelrc

{
  "presets": ["@babel/preset-env"]
}

NOTE: As of May 2020, Jest supports JSDom 16.* by default, rendering the below no longer necessary or relevant

解决方案

Jest 默认与 JSDom ^15.1.1 一起运行(自 Feb 17th, 2020 起),因此您需要手动更新才能使用 JSDom 16.2.0 安装 jest-environment-jsdom-sixteen.

首先为Jest安装最新的JSDom环境

npm i jest-environment-jsdom-sixteen --save-dev

并更改您的 package.json 以包括:

"scripts": {
  "test": "jest --env=jest-environment-jsdom-sixteen"
},

这将确保 Jest 是 运行 正确的环境。

您还需要通过安装 babel-plugin-transform-builtin-classes 来确保 Babel 正确处理内置 类(例如 class HTMLElement {}),如下所示:

npm i babel-plugin-transform-builtin-classes --save-dev

并添加到您的.babelrc以下

"plugins": [
  ["babel-plugin-transform-builtin-classes", {
    "globals": ["Array", "Error", "HTMLElement"]
  }]
]

不要安装babel-plugin-transform-es2015-classes,因为根据this issue

,这已经构成了 Babel 7 核心的一部分

可用的简化测试用例 here