如何测试组件的属性是否正确传递

huangapple go评论60阅读模式
英文:

How to test if component props is passing correctly

问题

I will provide the translated code portion:

考虑我有这个组件

function RankDialog(props: any) {
  const { visible = true, setVisible } = props;
  return (
    <Dialog
      visible={visible}
      className="rank-dialog"
      scrollBoxClassName="rank-scroll-box"
      alignBottom
      noMargin
      noContentPadding
      onClose={() => {
        setVisible(false);
      }}
      onCancel={() => {
        setVisible(false);
      }}
    >
      <Rank />
    </Dialog>
  );
}

If you need any further assistance, feel free to ask.

英文:

Consider I have this component

function RankDialog(props: any) {
  const { visible = true, setVisible } = props;
  return (
    <Dialog
      visible={visible}
      className="rank-dialog"
      scrollBoxClassName="rank-scroll-box"
      alignBottom
      noMargin
      noContentPadding
      onClose={() => {
        setVisible(false);
      }}
      onCancel={() => {
        setVisible(false);
      }}
    >
      <Rank />
    </Dialog>
  );
}

on my unit test, it said I missed the coverage of these lines

      onClose={() => {
        setVisible(false);
      }}
      onCancel={() => {
        setVisible(false);
      }}

How to write the unit test just to check if the props is passing correctly. I searched google it said I have to trigger the click of close and cancel. Is there any different way, as I may not know what is the close and cancel button looks like in order to query it correctly.

I'm thinking just to write a test to check if the Dialog.props.onClose is passed correctly.

I'm using @testing-library/react

答案1

得分: 1

你可以使用 jest.fn() 来创建 setVisible 的模拟函数,然后在调用 onCloseonCancel 时检查它是否已被调用以预期的值。这样,你无需担心 Dialog 组件的实现细节或查询关闭和取消按钮。

import { render } from "@testing-library/react";
import RankDialog from "./RankDialog";
import Dialog from "./Dialog"; // 导入 Dialog 组件

// 模拟 Dialog 组件
jest.mock("./Dialog", () => {
  return (props) => (
    <div
      onClick={props.onClose}
      onContextMenu={props.onCancel}
      data-testid="mock-dialog"
    >
      {props.children}
    </div>
  );
});

describe("RankDialog", () => {
  it("passes setVisible(false) to onClose and onCancel", () => {
    const setVisible = jest.fn();
    const { getByTestId } = render(
      <RankDialog visible={true} setVisible={setVisible} />
    );

    const mockDialog = getByTestId("mock-dialog");

    // 模拟 onClose
    mockDialog.click();
    expect(setVisible).toHaveBeenCalledWith(false);

    // 模拟 onCancel
    mockDialog.dispatchEvent(new MouseEvent("contextmenu", { bubbles: true }));
    expect(setVisible).toHaveBeenCalledTimes(2);
    expect(setVisible).toHaveBeenCalledWith(false);
  });
});

以上是代码的翻译部分。

英文:

You can use jest.fn() to create a mock function for setVisible, and then check if it has been called with the expected value when onClose and onCancel are called. This way, you don't need to worry about the implementation details of the Dialog component or querying the close and cancel buttons.

import { render } from &quot;@testing-library/react&quot;;
import RankDialog from &quot;./RankDialog&quot;;
import Dialog from &quot;./Dialog&quot;; // Import the Dialog component

// Mock the Dialog component
jest.mock(&quot;./Dialog&quot;, () =&gt; {
  return (props) =&gt; (
    &lt;div
      onClick={props.onClose}
      onContextMenu={props.onCancel}
      data-testid=&quot;mock-dialog&quot;
    &gt;
      {props.children}
    &lt;/div&gt;
  );
});

describe(&quot;RankDialog&quot;, () =&gt; {
  it(&quot;passes setVisible(false) to onClose and onCancel&quot;, () =&gt; {
    const setVisible = jest.fn();
    const { getByTestId } = render(
      &lt;RankDialog visible={true} setVisible={setVisible} /&gt;
    );

    const mockDialog = getByTestId(&quot;mock-dialog&quot;);

    // Simulate onClose
    mockDialog.click();
    expect(setVisible).toHaveBeenCalledWith(false);

    // Simulate onCancel
    mockDialog.dispatchEvent(new MouseEvent(&quot;contextmenu&quot;, { bubbles: true }));
    expect(setVisible).toHaveBeenCalledTimes(2);
    expect(setVisible).toHaveBeenCalledWith(false);
  });
});

答案2

得分: 0

你可以将一个 Jest mock 函数传递给 RankDialog 组件的 setVisible prop,从而可以捕获对该函数的调用并对其进行断言。

这两个测试用例检查当点击 "close" 和 "cancel" 按钮时,setVisible 函数是否被调用,并且传入了预期的参数(false)。在测试库生态系统中,使用 @testing-library/user-event 来模拟用户事件是推荐的方法,因为它被认为更接近真实用户交互,可以确保测试更接近实际用户行为。

在第一个测试用例中,使用 screen.getByRole("button", { name: /close/i }) 查询 "close" 按钮,然后使用 userEvent.click(closeBtn) 模拟点击。接着,使用 expect 来断言 setVisible 函数是否被传入 false 参数。

在第二个测试用例中,类似地查询 "cancel" 按钮,使用 screen.getByRole("button", { name: /cancel/i })

这种方法允许你测试 RankDialog 组件的预期行为,而不依赖于按钮外观的具体实现细节,这使得测试更能抵御 UI 的变化。

英文:

You can pass a Jest mock function as the setVisible prop to the RankDialog component, allowing you to capture calls to the function and assert on them.

These two test cases check if the setVisible function is called with the expected argument (false) when the "close" and "cancel" buttons are clicked. Using @testing-library/user-event to simulate user events is the recommended approach in the testing library ecosystem as mentioned here, as it is said to closely mimic real user interactions and ensure that the tests are closer to actual user behavior.

import { render, screen } from &quot;@testing-library/react&quot;;
import userEvent from &quot;@testing-library/user-event&quot;;

import RankDialog from &quot;./RankDialog&quot;;

describe(&quot;RankDialog&quot;, () =&gt; {
  it(&quot;should call setVisible with false when clicking the close button&quot;, async () =&gt; {
    // Create a mock function for setVisible
    const setVisible = jest.fn();
    // Render the RankDialog component with necessary props
    render(&lt;RankDialog visible={true} setVisible={setVisible} /&gt;);

    // Query for the element representing the &quot;close&quot; button
    const closeBtn = screen.getByRole(&quot;button&quot;, { name: /close/i });
    // Simulate a click on the &quot;close&quot; button
    await userEvent.click(closeBtn);
    // Assert that the setVisible function is called with false as an argument
    expect(setVisible).toHaveBeenCalledWith(false);
  });

  it(&quot;should call setVisible with false when clicking the cancel button&quot;, async () =&gt; {
    // Create a mock function for setVisible
    const setVisible = jest.fn();
    // Render the RankDialog component with the necessary props
    render(&lt;RankDialog visible={true} setVisible={setVisible} /&gt;);

    // Query for the element representing the &quot;cancel&quot; button
    const cancelBtn = screen.getByRole(&quot;button&quot;, { name: /cancel/i });
    // Simulate a click on the &quot;cancel&quot; button
    await userEvent.click(cancelBtn);
    // Assert that the setVisible function is called with false as an argument
    expect(setVisible).toHaveBeenCalledWith(false);
  });
});

In the first test case, the "close" button is queried using screen.getByRole(&quot;button&quot;, { name: /close/i }) and a click is simulated on it using userEvent.click(closeBtn). Then, you use expect to assert that the setVisible function is called with false as an argument.

In the second test case, you do a similar action by querying for the "cancel" button. screen.getByRole(&quot;button&quot;, { name: /cancel/i }) has been used to query for the button.

This approach allows you to test the expected behavior of the RankDialog component without relying on the specific implementation details of the buttons' appearance, which makes the tests more resilient to changes in the UI.

huangapple
  • 本文由 发表于 2023年4月11日 11:57:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/75982287.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定