我可以用JSDOM欺骗instanceof吗?

问题描述

我有一个要测试的React类,如果在开始时检查,则该类具有该类:

 import React from 'react'
 import Dropdown from './Dropdown'
 import './AddProduct.css'

 function AddProduct() {
   return (
    <div className="Box">
        <h1>Add Product</h1>
        <p>
        <input type="text" placeholder="Name"></input>
       <Dropdown />
        </p>
        
       
       <p>
       <input type="text" placeholder="Stock"></input>
       </p>

       <div>
       <button className="btn2">Save</button>
       </div>
    
      
    </div>
   )
}

export default AddProduct

我尝试使用if (!(root instanceof window.HTMLElement)) { throw new Error('No HTML element was supplied. ); } 传递假元素,但它没有“欺骗”检查的实例。

jsdom

我研究了传入的内容

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

它看起来不像window.HTMLElement:

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. );
}

如何模拟 console.log src/main.jsx:20 [object HTMLdivelement] console.log src/main.jsx:21 function console.log src/main.jsx:22 object ,以便可以测试此类?

解决方法

您可以通过将window的属性分配为global的属性来模拟它们。在分配全局属性和使用它创建元素之间,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)
    })
})

Demo