DEV Community

Hodeem
Hodeem

Posted on • Edited on

How to test the Hidden API (from Material UI)

If you want to hide or display the element tree nested inside <Hidden> tags for a jest test, here's how it can be done.

Getting started

Let's say that we're testing if "Hey" is rendered correctly:

describe("Testing Hidden API", () => {

    render(
        <Hidden xsDown>
            <p>Hey</p>
        </Hidden>
    );

    it("'Hey' is visible",() => {
        expect(screen.getByText("Hey")).toBeVisible();
    }
}
Enter fullscreen mode Exit fullscreen mode

Note: The render method is imported from @testing-library/react

If we want 'Hey' to be visible, we need the xsDown property of the <Hidden> component to evaluate to false when the test runs.

From Material UI's breakpoint documentation, we can see that we need to simulate the window's innerWidth being a value greater than or equal to 600px.

Making it work

While you may think that only changing the window's dimensions in the manner below is sufficient, this will not produce the desired result:

window.innerWidth = 600;
window.dispatchEvent(new Event("resize"));
Enter fullscreen mode Exit fullscreen mode

The key is to mock the window's matchMedia() method.

describe("Testing Hidden API", () => {

    beforeEach(() => {
        Object.defineProperty(window, "matchMedia", {
            writable: true,
            value: jest.fn().mockImplementation(query => ({
                matches: !(query === "(max-width: 599px)"),
                addListener: jest.fn(),
                removeListener: jest.fn()
            }))
        });

        render(
            <Hidden xsDown>
                <p>Hey</p>
            </Hidden>
        );
    });

    it("Hey is visible",() => {
        expect(screen.getByText("Hey")).toBeVisible();
    }
}
Enter fullscreen mode Exit fullscreen mode

Why does this work?

When the <Hidden> component is rendered, it calls the matchMedia function with the corresponding media query for each specified breakpoint . For example, for xsDown, it would use the media query (max-width: 599px).

PS: This is why it wasn't necessary to include the previous logic (window.innerWidth = 600; ...) to make this test work. However, depending on your test you may need to change your dimensions in such a manner.

The matchMedia function returns a MediaQueryList object, which represents the result of the media query evaluation. The matches property of this object indicates whether the media query condition evaluates to true or false.

The Hidden component listens for changes in the matches property of the MediaQueryList objects for each breakpoint.

Whenever the matches property changes (i.e., when the viewport size or browser window is resized), the Hidden component updates its state based on the new visibility status for each breakpoint.

So, by returning false for the matches property in the mock implementation we make the children of the <Hidden> component visible. If we wanted to hide the children of the <Hidden> component then we would return true for the matches property.

If you liked this article, then please support me

Top comments (0)