首页 > 解决方案 > 我可以用 JSDOM 欺骗 instanceof 吗?

问题描述

我有一个我想测试的反应类,如果在开始时检查这个类:

if (!(root instanceof window.HTMLElement)) {
   throw new Error('No HTML element was supplied. );
}

我试图传递一个假元素,jsdom但它并没有“欺骗”instanceof 检查。

const doc = (new JSDOM()).window.document;
const root = doc.createElement("div");
const pizza = new Builder(root);
expect(pizza).toBeDefined();

我查看了传入的内容

if (!(root instanceof window.HTMLElement)) {
  console.log(Object.prototype.toString.call(root));
  console.log(typeof window.HTMLElement)
  console.log(typeof root)
  throw new Error('No HTML element was supplied. );
}

它看起来一点也不像 window.HTMLElement:

    console.log src/main.jsx:20
      [object HTMLDivElement]
    console.log src/main.jsx:21
      function
    console.log src/main.jsx:22
      object

我怎样才能模拟,window.HTMLElement以便我可以测试这个类?

标签: javascriptreactjsjsdom

解决方案


window您可以通过将它们分配为 的属性来模拟 的属性global。will的实例JSDOM在分配全局属性和使用它创建元素之间需要相同,否则实例HTMLElement也会不同。为了解决这个限制,我们将其引用为中jsDomInstance设置的单个变量beforeEach,而不是实例化多个副本。

const { JSDOM } = require('jsdom')

const { instanceofCheck } = require('./instanceofCheck')
// const instanceofCheck = x => x instanceof window.HTMLElement

describe('JSDOM tests', () => {
    let jsDomInstance

    beforeEach(() => {
        jsDomInstance = new JSDOM()
        global.HTMLElement = jsDomInstance.window.HTMLElement
    })

    it('passes instanceof check', () => {
        expect(
            instanceofCheck(
                jsDomInstance.window.document.createElement('div')
            )
        ).toBe(true)
    })
})

演示


推荐阅读