1

我什至无法为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

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

我缺少什么来测试<MyForm />组件?对我来说似乎很标准。

4

2 回答 2

1

我也可以重现您的问题,看起来 react-jsonschema-form 与fireEventor不兼容userEvent

但是,使用 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");
});
于 2021-02-19T12:49:01.023 回答
0

就您而言,您正在fluent-ui为您的 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.clearuserEvent.type

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

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

于 2021-02-25T13:49:12.157 回答