在StencilJS测试中使用jest-dom会引发错误

问题描述

我在StencilJS中进行了单元测试,其中使用的是jest-dom中的笑话匹配器。当我运行测试时,它会引发错误

TypeError: Right-hand side of 'instanceof' is not an object
      at checkHtmlElement (node_modules/@testing-library/jest-dom/dist/utils.js:61:69)
      at Object.toHaveFormValues (node_modules/@testing-library/jest-dom/dist/to-have-form-values.js:75:31)
      at __EXTERNAL_MATCHER_TRAP__ (node_modules/expect/build/index.js:342:30)
      at Object.throwingMatcher [as toHaveFormValues] (node_modules/expect/build/index.js:343:15)

单元测试是:

import '@testing-library/jest-dom';
import { h } from '@stencil/core';
import { newSpecPage } from '@stencil/core/testing';
import { AgForm,FormRenderProps } from '../ag-form';
import {getByTestId} from "@testing-library/dom";

describe('ag-form',() => {
  it('sets initial string value',async () => {
    type TestFormValues = {
      stringValue: string;
    };

    const initialValues: TestFormValues = {
      stringValue: 'foo',};

    const page = await newSpecPage({
      components: [AgForm],template: () => (
        <ag-form
          initialValues={initialValues}
          renderer={(props: FormRenderProps<TestFormValues>) => {
            const { inputProps } = props;
            return (
              <form data-testid="test-form">
                <input {...inputProps('stringValue')} />
              </form>
            );
          }}
        />
      ),});

    const formElement = getByTestId(page.body,'test-form')
    expect(formElement).toHaveFormValues(initialValues);
  });
});

函数在jest-dom中引发错误,该错误正在检查是否将有效的HTMLElement传递给匹配器:

function checkHtmlElement(htmlElement,...args) {
  checkHasWindow(htmlElement,...args);
  const window = htmlElement.ownerDocument.defaultview;

  if (!(htmlElement instanceof window.HTMLElement) && !(htmlElement instanceof window.SVGElement)) {
    throw new HtmlElementTypeError(htmlElement,...args);
  }
}

有趣的是,错误来自if语句的右侧(因为window.SVGElement未定义),但是我认为实际的问题是它不应该进入代码的这一部分。在该if语句的左侧,htmlElement instanceof window.HTMLElement的校验返回为假,因为htmlElement的类型为HTMLFormElement,而window.HTMLElement似乎是{{1 }}。

所以我的问题是-有没有一种方法可以使jest-dom与StencilJS单元测试一起使用,因为stencil设置的环境似乎不是jest-dom所期望的?

解决方法

我将在深入研究后回答我自己的问题,我认为答案只是玩笑不会与Stencil一起使用。

Jest的默认环境是jsdom,它用于在测试中创建类似于浏览器的环境。但是,Stencil会创建自己的环境,Jest会改用它,包括它自己的模拟DOM。这种模拟DOM实现尚未完全实现,因此,以jsdom编写的库(如jest-dom和DOM-testing-library)都将失败。