Jest の要約: グローバル オブジェクトのプロパティとメソッドを安全にモックする

WBOY
リリース: 2024-07-19 15:10:32
オリジナル
235 人が閲覧しました

Jest Recap: Safely Mock Properties and Methods of Global Objects

TL;DR:

  • オーバーライド/モックされたプロパティ/メソッドが他のテストに影響を与えることを避けたいと考えています。
  • ローカル オブジェクト (このテストによって作成および所有される) の場合は、使用できます (使用する必要があります)。
    • localObject.theAnswer = 42 および
    • localObject.calcTheAnswer = jest.fn(() => 42).
  • グローバルオブジェクトには使用する必要があります
    • jest.replaceProperty(globalObject, "theAnswer", 42) および
    • jest.spyOn(globalObject, "calcTheAnswer").mockReturnValue(42).
  • jest.restoreAllMocks() が afterEach() フックで呼び出されていることを確認してください。

何?

完璧な世界 コードベースではグローバルオブジェクトを操作する必要はありませんが、世界 コードベースは乱雑です - そしてテスト中です。

何としても避けたいのは、一方のテストが他方のテストに影響を与えることです。テストは、順序や一部のテストがスキップされたかどうかに関係なく、意味のあるものである必要があります。

プロパティのモック化

モック値への素朴なアプローチは、プロパティをテストで必要な値に設定することです。
この特定のテストが所有する (作成した) ローカル オブジェクトの値を変更する限り、これは問題ありません:

describe("override properties of local objects", () => {
    it("works and is harmless", () => {
        const myArray = [1];
        myArray.length = 0;
        expect(myArray).toHaveLength(0);
    });
    it("does not affect the next test", () => {
        const myArray = [1];
        expect(myArray).toHaveLength(1);
    });
});
ログイン後にコピー

グローバル オブジェクトに対してこれを行うと、面倒になります:

describe("don't override properties of global objects", () => {
    it("works before the property is overridden", () => {
        expect(window.innerWidth).toBeGreaterThan(0);
    });
    it("works, but is evil", () => {
        window.innerWidth = 0;
        expect(window.innerWidth).toBe(0);
    });
    it("fails in the test after the property was overridden", () => {
        expect(() => {
            expect(window.innerWidth).toBeGreaterThan(0); // <-- ERROR: expect(received).toBeGreaterThan(expected)
        }).toThrow(Error);
    });
});
ログイン後にコピー

これは jest.replaceProperty() が作成された目的です:

describe("use jest.replaceProperty() to override properties of global objects", () => {
    afterEach(() => {
        jest.restoreAllMocks();
    });
    it("works before the property is overridden", () => {
        expect(window.innerWidth).toBeGreaterThan(0);
    });
    it("works and is harmless", () => {
        jest.replaceProperty(window, "innerWidth", 0);
        expect(window.innerWidth).toBe(0);
    });
    it("does not affect the next test", () => {
        expect(window.innerWidth).toBeGreaterThan(0);
    });
});
ログイン後にコピー

モックメソッド

メソッドはプロパティと同様にモック化できます。

describe("override methods of local objects using jest.fn()", () => {
    it("works and is harmless", () => {
        const mySet = new Set([1]);
        mySet.has = jest.fn().mockReturnValue(false);
        expect(mySet.has(1)).toBeFalsy();
    });
    it("does not affect the next test", () => {
        const mySet = new Set([1]);
        expect(mySet.has(1)).toBeTruthy();
    });
});
ログイン後にコピー

グローバル オブジェクトに対して myObject.someFunction = jest.fn() を使用すると、テストが相互に依存し、その意味が失われる可能性があります。

describe("don't override methods of global objects using jest.fn()", () => {
    it("works before the method is overridden", () => {
        expect(document.getElementById("foo")).toBeNull();
    });
    it("works, but is evil", () => {
        const el = document.createElement("div");
        document.getElementById = jest.fn().mockReturnValue(el);

        expect(document.getElementById("foo")).toBe(el);
    });
    it("fails in the test after the property was overridden", () => {
        expect(() => {
            expect(document.getElementById("foo")).toBeNull(); // <-- ERROR: expect(received).toBeNull()
        }).toThrow(Error);
    });
});
ログイン後にコピー

グローバル オブジェクトのメソッドをどのようにモックすればよいでしょうか?これが jest.spyOn() の利点です:

describe("use jest.spyOn() to override methods of global objects", () => {
    afterEach(() => {
        jest.restoreAllMocks();
    });
    it("works before the method is overridden", () => {
        expect(document.getElementById("foo")).toBeNull();
    });
    it("works and is harmless", () => {
        const el = document.createElement("div");
        jest.spyOn(document, "getElementById").mockReturnValue(el);

        expect(document.getElementById("foo")).toBe(el);
    });
    it("does not affect the next test", () => {
        expect(document.getElementById("foo")).toBeNull();
    });
});
ログイン後にコピー

掃除しなければなりません

すべてのテストでシステムが同じ (新鮮でクリーンな) 状態であることを確認したい場合は、各テストの後にモックの状態を復元する必要があります。

最も簡単な解決策は、restoreMocks 構成プロパティを設定することです。

最も簡単なオプションは、afterEach() で jest.restoreAllMocks() を呼び出すことです

すべてのテストで何かをモックする方法

ファイル内のすべてのテストについてモックを作成したい場合があります。 jest.spyOn() と jest.replaceProperty() をトップレベルまたは description() ブロックで使用すると、最初のテストの実行後にすべてのモックがリセットされます。

トップレベルでは、jest.spyOn() や jest.replaceProperty() を使用せずに、プロパティとメソッドを安全にオーバーライドできます。

describe() ブロックのみをモックしたい場合は、beforeEach() フックでこれらの呼び出しを行う必要があります。

以上がJest の要約: グローバル オブジェクトのプロパティとメソッドを安全にモックするの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!