How to test the Hidden API (from Material UI)
Tags: react, jest, javascript
Published: 2023-06-14 23:06:53


If you want to hide or display the element tree nested inside [\<Hidden\>](https://mui.com/material-ui/api/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:

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

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

	it("'Hey' is visible",() => {
		expect(screen.getByText("Hey")).toBeVisible();
	}
}
```

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](https://mui.com/material-ui/customization/breakpoints/), 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:

```js
window.innerWidth = 600;
window.dispatchEvent(new Event("resize"));
```

The key is to mock the window's [`matchMedia()`](https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia) method.

```js
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();
	}
}
```


## 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`](https://developer.mozilla.org/en-US/docs/Web/API/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] (https://www.buymeacoffee.com/hmcodes)