これが私の最初のフロントエンドテストの経験です。このプロジェクトでは、jestスナップショットテストを使用していますが、エラーが発生しましたTypeError: window.matchMedia is not a function
コンポーネント内。
Jestのドキュメントを調べて、「Manual mocks」セクションを見つけましたが、その方法についてはまだわかりません。
jest docsには現在、「公式の」回避策があります。
window.matchMedia = jest.fn().mockImplementation(query => {
return {
matches: false,
media: query,
onchange: null,
addListener: jest.fn(),
removeListener: jest.fn(),
};
});
私はこのテクニックを使用して、さまざまなモックの問題を解決してきました。
describe("Test", () => {
beforeAll(() => {
Object.defineProperty(window, "matchMedia", {
value: jest.fn(() => { return { matches: true } })
});
});
});
または、常にモックしたい場合は、package.json
から呼び出されるmocks
ファイル内に置くことができます:"setupTestFrameworkScriptFile": "<rootDir>/src/tests/mocks.js",
Jestテストファイル(テストの上)にmatchMediaスタブを配置し、テストに合格できるようにします。
window.matchMedia = window.matchMedia || function() {
return {
matches : false,
addListener : function() {},
removeListener: function() {}
};
};
Jestは jsdom を使用してブラウザー環境を作成します。ただし、JSDomはwindow.matchMedia
をサポートしていないため、自分で作成する必要があります。
Jestの manual mocks はモジュールの境界で動作します。つまり、グローバルであるためにwindow.matchMedia
をモックするのに適切ではないように、ステートメントをrequire/importします。
したがって、2つのオプションがあります。
Window.matchMediaをエクスポートする独自のローカルmatchMediaモジュールを定義します。 -これにより、テストで使用する手動のモックを定義できます。
MatchMediaのモックをグローバルウィンドウに追加する setup file を定義します。
これらのオプションのいずれかを使用すると、少なくともテストの実行を許可するモックとして matchMedia polyfill を使用できます。異なる状態をシミュレートする必要がある場合は、プライベートメソッドで独自のメソッドを記述できます。 Jestに似た動作を設定するには fs
manual mock
この問題が発生しました。これらをjestGlobalMocks.tsでモックする必要がありました。
Object.defineProperty(window, 'matchMedia', {
value: () => {
return {
matches: false,
addListener: () => {},
removeListener: () => {}
};
}
});
Object.defineProperty(window, 'getComputedStyle', {
value: () => {
return {
getPropertyValue: () => {}
};
}
});
APIをモックできます。
describe("Test", () => {
beforeAll(() => {
Object.defineProperty(window, "matchMedia", {
value: jest.fn(() => {
return {
matches: true,
addListener: jest.fn(),
removeListener: jest.fn()
};
})
});
});
});
成功せずに上記のすべてを試してみました。 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';
ブーム! :)