首页 > 解决方案 > 在反应中模拟最终形式的提交

问题描述

我正在尝试通过提交表单来测试是否正在调用回调函数。我模拟了一个传递到 react-final-form 的 onSubmit 函数。如代码框和下面所示,我有一个带有 onSubmit 回调的简单表单。

export const MyForm = ({ onSubmit }) => (
  <Form
    onSubmit={onSubmit}
    render={({ handleSubmit }) => (
      <form onSubmit={handleSubmit} autoComplete="off">
        <Field
          label="Email"
          component={Input}
          name="email"
          type="email"
          autoComplete="off"
        />
        <button>Submit</button>
      </form>
    )}
  />
);

当我模拟按钮上的单击事件时,我希望它调用模拟函数。


  it("should call onSubmit when the button is click", () => {
    const button = wrapper.find("button");
    expect(button.length).toBeGreaterThan(0);
    button.at(0).simulate("click");
    expect(mockSubmit).toHaveBeenCalled();
  });

任何帮助将不胜感激。

代码沙盒

标签: javascriptreactjsjestjsenzymereact-final-form

解决方案


您需要进行模拟submit才能提交表单。

至于Warning: An update to ReactFinalForm inside a test was not wrapped in act(...).,您在测试中的提交处理程序中使用了一个承诺,这会导致表单验证、提交和状态更新是异步的。

act()提供围绕预期组件更新的范围,当组件执行此范围之外的操作时,您将收到此警告。由于在测试中提交处理程序是异步的,更新将发生在act()函数之外,并会给你这个错误。

有两种方法可以解决这个问题,使提交处理程序通过jest.fn().

const mockSubmit = jest.fn();

如果您需要保持此异步,您将需要对提交承诺采取行动/等待。这意味着您需要创建一个已解析的承诺值并让一个模拟函数解析它。

  const promise = Promise.resolve();
  const mockSubmit = jest.fn(() => promise);

  beforeEach(() => {
    wrapper = mount(<MyForm onSubmit={mockSubmit} />);
  });

  it("should call onSubmit when the button is click 2", async () => {
    const button = wrapper.find("form");
    expect(button.length).toBeGreaterThan(0);
    button.at(0).simulate("submit");
    expect(mockSubmit).toHaveBeenCalled();

    await act(() => promise);
  });

推荐阅读