简体   繁体   English

测试失败,因为 React 测试库中的 object 不正确

[英]Test is failing as the object is incorrect in React Testing Library

Component to test -要测试的组件-

import { useState } from "react";

const UserForm = ({ onUserAdd }) => {
  const [name, setName] = useState("");
  const [email, setEmail] = useState("");

  const handleSubmit = (e) => {
    e.preventDefault();
    onUserAdd({ name, email });
  };

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label>Name</label>
        <input value={name} onChange={(e) => setName(e.target.value)} />
      </div>
      <div>
        <label>Email</label>
        <input value={email} onChange={(e) => setEmail(e.target.value)} />
      </div>
      <button onClick={handleSubmit}>Add User</button>
    </form>
  );
};

export default UserForm;

Failing Test Case -失败的测试用例-

test("it calls onUserAdd when the form is submitted", async () => {
  // BETTER IMPLEMENTATION
  const mock = jest.fn();

  // Render - the component
  render(<UserForm onUserAdd={mock} />);

  // Find 2 inputs (name, email in this case)
  const [nameInput, emailInput] = screen.getAllByRole("textbox");

  // Simulate typing in a name
  await user.click(nameInput);
  await user.keyboard("jane");

  // Simulate typing in a email
  await user.click(emailInput);
  await user.keyboard("abc@abc.com");

  // Find the submit button
  const button = screen.getByRole("button");

  // Simulate clicking the submit button
  await user.click(button);

  // Assertion - make sure 'onUserAdd' gets called with name/email
  expect(mock).toHaveBeenCalled();
  expect(mock).toHaveBeenCalledWith({ name: "jane", email: "abc@abc.com" });
});

Error -错误 -

- Expected
+ Received

  Object {
-   "email": "abc@abc.com",
-   "name": "jane",
+   "email": "",
+   "name": "",
  },

Let me know what I am doing wrong here.让我知道我在这里做错了什么。

Codesandbox Link - https://codesandbox.io/s/morning-microservice-xxh0mw?file=/src/UserForm.test.js Codesandbox 链接- https://codesandbox.io/s/morning-microservice-xxh0mw?file=/src/UserForm.test.js

PS - Since I am learning react testing, I used await for every event, let me know if this is a correct approach as well. PS -因为我正在学习反应测试,所以我对每个事件都使用await ,让我知道这是否也是一种正确的方法。 Thanks.谢谢。

Generally looks ok but I find CodeSandbox to be really buggy when dealing with react testing library.通常看起来不错,但我发现 CodeSandbox 在处理 React 测试库时确实存在问题。 I replaced your user.click s and user.keyboard s with user.type which I find more human readable and concise to work with and it seems to work:我用user.type替换了你的user.click s 和user.keyboard s,我发现它更易于阅读和简洁,而且它似乎有效:

test("it calls onUserAdd when the form is submitted", async () => {
  const mock = jest.fn();

  // Render - the component
  render(<UserForm onUserAdd={mock} />);

  // Find 2 inputs (name, email in this case)
  const [nameInput, emailInput] = screen.getAllByRole("textbox");

  // Simulate typing in a name
  await user.type(nameInput, "jane"); // <--here-<<

  // Simulate typing in a email
  await user.type(emailInput, "abc@abc.com"); // <--and here-<<

  // Find the submit button
  const button = screen.getByRole("button");

  // Simulate clicking the submit button
  await user.click(button);

  // Assertion - make sure 'onUserAdd' gets called with name/email
  expect(mock).toHaveBeenCalled();
  expect(mock).toHaveBeenCalledWith({ name: "jane", email: "abc@abc.com" });
});

And yes, you are correct wo await every user action.是的,您是正确的,我await每个用户操作。 Although RTL docs recommend to use the new setup const user = userEvent.setup() instead of calling the API directly尽管 RTL 文档建议使用新的设置const user = userEvent.setup()而不是直接调用 API

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM