Jest:期望组件内部的函数已被调用

az31mfrm  于 2023-06-27  发布在  Jest
关注(0)|答案(1)|浏览(125)

这段简单的代码灵感来自https://testing-library.com/docs/example-react-formik/

import React from "react";
import { Formik, Field, Form } from "formik";

const sleep = (ms: any) => new Promise((r) => setTimeout(r, ms));

export const MyForm = () => {
  const handleSubmit = async (values: any) => {
    await sleep(500);
    console.log(values);
  };

  return (
    <div>
      <Formik
        initialValues={{
          firstName: "",
        }}
        onSubmit={handleSubmit}
      >
        <Form>
          <label htmlFor="firstName">First Name</label>
          <Field id="firstName" name="firstName" placeholder="Jane" />

          <button type="submit">Submit</button>
        </Form>
      </Formik>
    </div>
  );
};

和测试:

import React from "react";
import { render, screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";

import { MyForm } from "./MyForm";

test("rendering and submitting a basic Formik form", async () => {
  const handleSubmit = jest.fn(); // this doing nothing
  render(<MyForm />);
  const user = userEvent.setup();

  await user.type(screen.getByLabelText(/first name/i), "John");

  await user.click(screen.getByRole("button", { name: /submit/i }));

  await waitFor(() => expect(handleSubmit).toHaveBeenCalledTimes(1));
});

Console.log打印了输入的值:{ firstName: 'John' },但测试失败,因为它知道没有调用handleSubmit
这段代码出了什么问题?

3pmvbmvn

3pmvbmvn1#

因为您没有将模拟handleSubmit传递给<MyForm/>组件。您应该将它作为onSubmit prop传递给组件,并在内部handleSubmit事件处理程序执行时调用它。
让我们看看RTL official formik testing example
MyForm.tsx

export const MyForm = ({onSubmit}) => {
  const handleSubmit = async (values) => {
    await sleep(500)
    onSubmit(values)
  }
  return <div>...</div>
}

MyForm.test.tsx

test('rendering and submitting a basic Formik form', async () => {
  const handleSubmit = jest.fn();
  render(<MyForm onSubmit={handleSubmit} />);

  await user.click(screen.getByRole('button', {name: /submit/i}));

  await waitFor(() => expect(handleSubmit).toHaveBeenCalledTimes(1));
})

你看到官方示例和你的代码之间的区别了吗?

相关问题