Fix Jest Matchmedia Not Defined

3 min read.

If you're testing React components that use window.matchMedia, Jest will crash with TypeError: window.matchMedia is not a function. This browser API doesn't exist in the jsdom test environment.

Why it happens

Jest runs tests in Node.js with jsdom, which doesn't implement window.matchMedia. Any code that calls matchMedia — common in responsive components, media query hooks, or UI libraries — will fail.

The fix

Add this mock to your Jest setup file:

// jest.setup.ts
Object.defineProperty(window, 'matchMedia', {
  writable: true,
  value: jest.fn().mockImplementation(query => ({
    matches: false,
    media: query,
    onchange: null,
    addListener: jest.fn(),
    removeListener: jest.fn(),
    addEventListener: jest.fn(),
    removeEventListener: jest.fn(),
    dispatchEvent: jest.fn(),
  })),
});

If you're using an older version of Jest/jsdom, you might need addListener and removeListener (shown above). Newer versions use addEventListener/removeEventListener instead.

Make it return true for specific queries

If your test needs matchMedia to return matches: true:

window.matchMedia = jest.fn().mockImplementation(query => {
  if (query === '(min-width: 768px)') {
    return {
      matches: true,
      media: query,
      onchange: null,
      addListener: jest.fn(),
      removeListener: jest.fn(),
      addEventListener: jest.fn(),
      removeEventListener: jest.fn(),
      dispatchEvent: jest.fn(),
    };
  }
  return {
    matches: false,
    media: query,
    onchange: null,
    addListener: jest.fn(),
    removeListener: jest.fn(),
    addEventListener: jest.fn(),
    removeEventListener: jest.fn(),
    dispatchEvent: jest.fn(),
  };
});

Verify it works

it('renders differently on mobile', () => {
  render(<MyComponent />);
  expect(window.matchMedia).toHaveBeenCalled();
});

That's it. The mock gives you a working matchMedia that behaves predictably in tests.

Latest Posts