Search code examples
reactjsunit-testingjestjsreact-testing-library

How to test a dropdown component in react using react testing library jest?


I am trying to test the dropdown component using react testing with jest,however, I did try to use a different approach but did not find any solution, can anyone please help ? Also if you can share how this is been achieved would be great.

Please see the code I have tried so far:

Dropdown component

 <div>
                <button data-testid="dropdownBtn" className="dropdownBtn" onClick={handleDropdownClick}>
                    {placeholder}
                    <span>
                        <FontAwesomeIcon icon={faChevronDown} />
                    </span>
                </button>
                {showDropdown && (
                    <div data-testid="dropdownItems" className="dropdownItems">
                        {options.map((option) => (
                            <Link data-testid="items" to={option.to} key={option.value}>
                                {option.label}
                            </Link>
                        ))}
                    </div>
                )}
            </div>

Testing the component:

import { render, screen, fireEvent } from "@testing-library/react";
import { BrowserLink, Router } from "react-router-dom";

import Dropdown from "./Dropdown";

const testOptions = [
    { value: "item1", label: "item 1", to: "/about" },
    { value: "item1", label: "item 1", to: "/about" },
];
    it("handles dropdown click", async () => {
            render(<Dropdown placeholder="placeholder name" options={testOptions} />);
            const dropdwonBtn = screen.getByTestId("dropdownBtn");
            fireEvent.click(dropdwonBtn);
            expect(dropdwonBtn).toHaveBeenCalledTimes(1);
        });

The Error I am getting: error Image

Thanks


Solution

  • I think there are a couple of issues with your test code:

    1 - As the error message suggests, I believe you need to wrap your test component with BrowserRouter for the test to progress: render(<BrowserRouter><YourComponent/></BrowserRouter>);

    2 - I noticed your test assertion expect(dropdwonBtn).toHaveBeenCalledTimes(1); is incorrect. That is because toHaveBeenCalledTimes is an assertion for checking that a certain function has been called a certain amount of times, but you are asserting it on a element rather than a function (dropdownBtn) so that would fail your test as well. Instead, you want to check that after your click the dropdown menu has actually appeared and you can do that by asserting:

    // after click event
    const dropdownMenu = screen.getByTestId('dropdownItems');
    expect(dropdownMenu).toBeInTheDocument();