1

我在 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返回结果为 false,htmlElement类型为HTMLFormElementwhilewindow.HTMLElement似乎是 a MockHtmlElement

所以我的问题是 - 有没有办法让 jest-dom 与 StencilJS 单元测试一起工作,因为看起来 stencil 设置的环境不是 jest-dom 所期望的?

4

1 回答 1

0

在深入研究之后,我将回答我自己的问题,我认为答案只是 jest-dom 不适用于 Stencil。

Jest 的默认环境是 jsdom,它用于在测试中创建类似浏览器的环境。然而,Stencil 创建了自己的 Jest 使用的环境,包括它自己的模拟 DOM。这个模拟 DOM 实现(还没有)功能齐全,所以在编写时考虑到 jsdom 的库,比如 jest-dom 和 DOM-testing-library 都失败了。

于 2020-11-27T16:30:01.517 回答