【问题标题】:How to test react-jsonschema-form components with @testing-library/user-event如何使用 @testing-library/user-event 测试 react-jsonschema-form 组件
【发布时间】:2021-01-27 08:47:27
【问题描述】:

我连最简单的react jsonschema form 测试都写不出来。因为对输入元素的更改似乎没有反映在 dom 中。

给定一个像这样的最小形式:

const schema = {
  title: "Todo", type: "object",
  properties: {
    title: { type: "string", title: "Title", default: "A new task" }
  }
};

const formData = { title: "First task aaa" };

export class MyForm extends React.Component {
  render() { return <Form schema={schema} formData={formData} />; }
}

一个最小的测试看起来像

test("changes input", async () => {
  render(<MyForm />);
  const input = screen.getByRole("textbox");
  expect(input.value).toBe("First task aaa");
  await userEvent.type(input, "567890", { delay: 10 });
  expect(input.value).toBe("567890");
});

(在Codesandbox完成样本。)

在表单字段中输入文本后,First task aaa 应替换为 567890。不幸的是,它不是。input.value 保留值First task aaa

我尝试了许多触发事件的变体并等待结果,但输入元素的值始终保持不变。

我在测试&lt;MyForm /&gt; 组件时缺少什么?对我来说似乎很标准。

【问题讨论】:

    标签: reactjs unit-testing react-testing-library react-jsonschema-forms user-event


    【解决方案1】:

    我也可以重现您的问题,但看起来 react-jsonschema-form 无法与 fireEventuserEvent 配合使用。

    但是,使用 react-doms Simulate 函数,它确实有效:

    import React from "react";
    import { Simulate } from 'react-dom/test-utils'
    import { render } from "@testing-library/react";
    import { MyForm } from "./form.js";
    
    // Tests in codesandbox fail in Safari - use Firefox or Chrome
    // click on the "Tests" tab in the upper right.
    
    test("changes input", async () => {
      const { getByLabelText } = render(<MyForm />);
      const input = getByLabelText("Title");
      expect(input.value).toBe("First task aaa");
    
      Simulate.change(input, { target: { value: '567890' }})
    
      expect(input.value).toBe("567890");
    });
    

    【讨论】:

      【解决方案2】:

      就您的 UI 使用 fluent-ui 表单库而言,这会将输入值与您的 formData.title 字段绑定。这可能会中断userEvent.type 操作。为了简单地测试userEvent.type的功能,你可以用纯输入元素制作你的表单组件,并将你的默认值绑定为输入元素的defaultValue。

      例如:

      export class MyForm extends React.Component {
        render() {
          return <input type="text" defaultValue="First task aaa" />;
        }
      }
      

      如果您会在测试输出中看到以下错误:

      expect(element).toHaveValue(567890)
      
          Expected the element to have value:
            567890
          Received:
            First task aaa567890
      
            13 |   expect(input).toHaveValue("First task aaa");
            14 |   userEvent.type(input, '567890');
          > 15 |   expect(input).toHaveValue('567890');
               |                 ^
            16 | });
      
      

      如您所见,userEvent.type 会将附加输入附加到当前值。因此,您可以只使用Simulate.change 功能或在userEvent.type 行之前使用userEvent.clear 功能,如下所示。

      test("changes input", async () => {
        render(<MyForm />);
        const input = screen.getByRole("textbox");
      
        expect(input).toHaveValue("First task aaa");
        userEvent.clear(input);
        userEvent.type(input, "567890");
        expect(input).toHaveValue("567890");
      });
      

      此答案可能对您的问题有所帮助。
      干杯!

      【讨论】:

        猜你喜欢
        • 2019-10-30
        • 2019-06-14
        • 2019-08-29
        • 2021-11-30
        • 1970-01-01
        • 2019-05-21
        • 1970-01-01
        • 2019-11-11
        • 2021-02-23
        相关资源
        最近更新 更多