web-dev-qa-db-ja.com

Jestテストが失敗しました:TypeError:window.matchMediaは関数ではありません

これが私の最初のフロントエンドテストの経験です。このプロジェクトでは、jestスナップショットテストを使用していますが、エラーが発生しましたTypeError: window.matchMedia is not a functionコンポーネント内。

Jestのドキュメントを調べて、「Manual mocks」セクションを見つけましたが、その方法についてはまだわかりません。

33
TIJ

jest docsには現在、「公式の」回避策があります。

window.matchMedia = jest.fn().mockImplementation(query => {
  return {
    matches: false,
    media: query,
    onchange: null,
    addListener: jest.fn(),
    removeListener: jest.fn(),
  };
});

JSDOMで実装されていないモッキングメソッド

29
Selrond

私はこのテクニックを使用して、さまざまなモックの問題を解決してきました。

describe("Test", () => {
  beforeAll(() => {  
    Object.defineProperty(window, "matchMedia", {
      value: jest.fn(() => { return { matches: true } })
    });
  });
});

または、常にモックしたい場合は、package.jsonから呼び出されるmocksファイル内に置くことができます:"setupTestFrameworkScriptFile": "<rootDir>/src/tests/mocks.js",

ref: setupTestFrameworkScriptFile

23

Jestテストファイル(テストの上)にmatchMediaスタブを配置し、テストに合格できるようにします。

window.matchMedia = window.matchMedia || function() {
    return {
        matches : false,
        addListener : function() {},
        removeListener: function() {}
    };
};
13

Jestは jsdom を使用してブラウザー環境を作成します。ただし、JSDomはwindow.matchMediaをサポートしていないため、自分で作成する必要があります。

Jestの manual mocks はモジュールの境界で動作します。つまり、グローバルであるためにwindow.matchMediaをモックするのに適切ではないように、ステートメントをrequire/importします。

したがって、2つのオプションがあります。

  1. Window.matchMediaをエクスポートする独自のローカルmatchMediaモジュールを定義します。 -これにより、テストで使用する手動のモックを定義できます。

  2. MatchMediaのモックをグローバルウィンドウに追加する setup file を定義します。

これらのオプションのいずれかを使用すると、少なくともテストの実行を許可するモックとして matchMedia polyfill を使用できます。異なる状態をシミュレートする必要がある場合は、プライベートメソッドで独自のメソッドを記述できます。 Jestに似た動作を設定するには fs manual mock

12
riscarrott

この問題が発生しました。これらをjestGlobalMocks.tsでモックする必要がありました。

    Object.defineProperty(window, 'matchMedia', {
      value: () => {
        return {
          matches: false,
          addListener: () => {},
          removeListener: () => {}
        };
      }
    });

    Object.defineProperty(window, 'getComputedStyle', {
      value: () => {
        return {
          getPropertyValue: () => {}
        };
      }
    });
8
techguy2000

APIをモックできます。

describe("Test", () => {
  beforeAll(() => {
    Object.defineProperty(window, "matchMedia", {
      value: jest.fn(() => {
        return {
          matches: true,
          addListener: jest.fn(),
          removeListener: jest.fn()
        };
      })
    });
  });
});
1
Pål Thingbø

成功せずに上記のすべてを試してみました。 matchMedia.jsをmocksフォルダーに追加してくれました。 @ techguy2000のコンテンツで埋めました:

// __mocks__/matchMedia.js
'use strict';

Object.defineProperty(window, 'matchMedia', {
    value: () => ({
        matches: false,
        addListener: () => {},
        removeListener: () => {}
    })
});

Object.defineProperty(window, 'getComputedStyle', {
    value: () => ({
        getPropertyValue: () => {}
    })
    });

module.exports = window;

次に、これをsetup.jsにインポートしました

import matchMedia from '../__mocks__/matchMedia';

ブーム! :)

0
arakno