Jest test fails : TypeError: window.matchMedia is not a function

ghz 6months ago ⋅ 180 views

This is my first front-end testing experience. In this project, I'm using Jest snapshot testing and got an error TypeError: window.matchMedia is not a function inside my component.

I go through Jest documentation, I found the "Manual mocks" section, but I have not any idea about how to do that yet.

Answers

When using Jest for testing, you might encounter an error related to window.matchMedia if your component relies on it. This is because Jest runs in a Node environment, which does not have a window.matchMedia implementation by default.

To resolve this issue, you can mock window.matchMedia in your test setup file. Here's how to do it:

  1. Create a setup file for Jest: This file will include global setup and teardown operations. You can name it jest.setup.js (or any name you prefer).

  2. Configure Jest to use this setup file: Update your jest.config.js or package.json to include the setup file.

  3. Mock window.matchMedia in the setup file: Implement a mock function for window.matchMedia.

Step-by-Step Guide

Step 1: Create a Setup File

Create a new file in your project, for example jest.setup.js.

Step 2: Configure Jest to Use the Setup File

If you're using a jest.config.js file, add the following:

// jest.config.js
module.exports = {
  setupFiles: ['./jest.setup.js'],
  // other configuration options
};

If you're configuring Jest through package.json, add the following:

// package.json
{
  "jest": {
    "setupFiles": ["./jest.setup.js"],
    // other configuration options
  }
}

Step 3: Mock window.matchMedia in the Setup File

Add the mock implementation for window.matchMedia in jest.setup.js:

// jest.setup.js
global.window.matchMedia = global.window.matchMedia || function() {
  return {
    matches: false,
    addListener: function() {},
    removeListener: function() {}
  };
};

Example Component and Test

Component Using matchMedia

Here's an example of a React component that uses matchMedia:

import React from 'react';

class MyComponent extends React.Component {
  componentDidMount() {
    if (window.matchMedia('(min-width: 600px)').matches) {
      console.log('Viewport is at least 600 pixels wide');
    } else {
      console.log('Viewport is less than 600 pixels wide');
    }
  }

  render() {
    return <div>My Component</div>;
  }
}

export default MyComponent;

Snapshot Test for the Component

Here's how you can write a snapshot test for this component using Jest:

import React from 'react';
import renderer from 'react-test-renderer';
import MyComponent from './MyComponent';

test('MyComponent renders correctly', () => {
  const tree = renderer.create(<MyComponent />).toJSON();
  expect(tree).toMatchSnapshot();
});

Run the Tests

Now, when you run your Jest tests, the window.matchMedia function will be mocked, and you shouldn't encounter the TypeError: window.matchMedia is not a function error anymore.

npm test

This setup ensures that your tests can run in a Node environment without failing due to the absence of window.matchMedia.