skip to Main Content

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

2

Answers


  1. 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 "@testing-library/react";
    import RankDialog from "./RankDialog";
    import Dialog from "./Dialog"; // Import the Dialog component
    
    // Mock the Dialog component
    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");
    
        // Simulate onClose
        mockDialog.click();
        expect(setVisible).toHaveBeenCalledWith(false);
    
        // Simulate onCancel
        mockDialog.dispatchEvent(new MouseEvent("contextmenu", { bubbles: true }));
        expect(setVisible).toHaveBeenCalledTimes(2);
        expect(setVisible).toHaveBeenCalledWith(false);
      });
    });
    
    
    Login or Signup to reply.
  2. 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 "@testing-library/react";
    import userEvent from "@testing-library/user-event";
    
    import RankDialog from "./RankDialog";
    
    describe("RankDialog", () => {
      it("should call setVisible with false when clicking the close button", async () => {
        // Create a mock function for setVisible
        const setVisible = jest.fn();
        // Render the RankDialog component with necessary props
        render(<RankDialog visible={true} setVisible={setVisible} />);
    
        // Query for the element representing the "close" button
        const closeBtn = screen.getByRole("button", { name: /close/i });
        // Simulate a click on the "close" button
        await userEvent.click(closeBtn);
        // Assert that the setVisible function is called with false as an argument
        expect(setVisible).toHaveBeenCalledWith(false);
      });
    
      it("should call setVisible with false when clicking the cancel button", async () => {
        // Create a mock function for setVisible
        const setVisible = jest.fn();
        // Render the RankDialog component with the necessary props
        render(<RankDialog visible={true} setVisible={setVisible} />);
    
        // Query for the element representing the "cancel" button
        const cancelBtn = screen.getByRole("button", { name: /cancel/i });
        // Simulate a click on the "cancel" 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("button", { 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("button", { 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search