Jestでwindow.matchMediaをモックする
React.js と Jest.js での "TypeError: window.matchMedia is not a function" のエラー
日本語訳
React.js と Jest.js を使用してプログラミングしている際に、"TypeError: window.matchMedia is not a function" というエラーが発生しています。このエラーは、Jest.js のテスト環境で window.matchMedia
関数が存在しないために起こります。
詳細説明
- エラーの原因
Jest.js のテスト環境では、window.matchMedia
関数がデフォルトで提供されていないため、この関数を呼び出すとエラーが発生します。 - Jest.js のテスト環境
Jest.js は、JavaScript コードのテストを自動化するためのフレームワークであり、ブラウザの環境を模倣する仮想環境を提供します。ただし、この仮想環境はブラウザのすべての機能を完全に再現しているわけではありません。 - window.matchMedia 関数
この関数は、ブラウザのウィンドウのメディアクエリ(スクリーンサイズ、解像度、色深度など)を検知し、その結果に基づいて条件分岐を行うために使用されます。
解決方法
このエラーを解決するには、以下の方法を使用できます。
-
Jest.js の jsdom ライブラリを使用する
jsdom
は、ブラウザの DOM 環境を模倣するライブラリです。Jest.js と組み合わせて使用することで、window.matchMedia
関数を提供することができます。package.json
ファイルにjsdom
を依存関係として追加し、Jest.js の設定ファイル(jest.config.js
)でjsdom
を使用するように設定します。
-
モック関数を定義する
例
// jest.config.js
module.exports = {
testEnvironment: 'jsdom',
};
// your-component.test.js
jest.mock('window', () => {
return {
matchMedia: jest.fn(() => ({
matches: false,
})),
};
});
// your-component.js
import { useMediaQuery } from 'react-responsive';
// ...
Jest で window.matchMedia をモックする
Jest で window.matchMedia
をモックする例コードについて説明します。
コード解説
jest.mock('window', () => {
return {
matchMedia: jest.fn(() => ({
matches: false,
})),
};
});
- matches: false
これは、window.matchMedia
関数が呼び出されたときに返されるオブジェクトのmatches
プロパティの値です。このプロパティは、メディアクエリがマッチしているかどうかを示します。 - matchMedia: jest.fn(() => ({ matches: false }))
この行は、window.matchMedia
関数をモックします。jest.fn()
を使用して、モック関数を定義し、その関数が呼び出されたときに実行されるコードを指定します。 - return { ... }
戻り値として、モックされたwindow
オブジェクトの定義を返します。 - jest.mock('window')
この行は、window
オブジェクトをモックします。つまり、実際のwindow
オブジェクトではなく、テスト用に作成された偽のwindow
オブジェクトを使用します。
使い方
このコードをテストファイルの先頭に追加することで、テストの実行中に window.matchMedia
関数がモックされ、テストコード内で自由に制御できるようになります。
import { useMediaQuery } from 'react-responsive';
// ...
test('useMediaQuery should return false when media query does not match', () => {
const { result } = render(<useMediaQuery query="screen and (min-width: 768px)" />);
expect(result.current).toBe(false);
});
このテストでは、useMediaQuery
カスタムフックが呼び出され、メディアクエリがマッチしているかどうかがチェックされます。モックされた window.matchMedia
関数のおかげで、メディアクエリがマッチしないように設定されているため、テストは成功します。
// jest.config.js
module.exports = {
testEnvironment: 'jsdom',
};
@testing-library/jest-dom を使用
@testing-library/jest-dom
は、Jest.js のテストをよりシンプルにするためのユーティリティを提供するライブラリです。このライブラリには、window.matchMedia
をモックするためのmatchMedia
カスタムマッチャーが含まれています。
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
// ...
test('useMediaQuery should return false when media query does not match', () => {
render(<useMediaQuery query="screen and (min-width: 768px)" />);
expect(window.matchMedia).toHaveProperty('matches', false);
});
手動でモックする
jest.fn()
を使用して、window.matchMedia
関数を手動でモックすることもできます。
jest.mock('window', () => {
return {
matchMedia: jest.fn(() => ({
matches: false,
})),
};
});
reactjs jestjs