「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > Jest の要約: グローバル オブジェクトのプロパティとメソッドを安全にモックする

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

2024 年 8 月 5 日に公開
ブラウズ:654

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() フックで呼び出されることを確認してください。

何?

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

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

プロパティのモック化

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

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); // 



これが 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(); // 



グローバル オブジェクトのメソッドをどのようにモックすればよいでしょうか?これが 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() フックでこれらの呼び出しを行う必要があります。

リリースステートメント この記事は次の場所に転載されています: https://dev.to/htho/jest-recap-safely-mock-properties-and-methods-of-global-objects-3ph8?1 侵害がある場合は、study_golang@163 までご連絡ください。 .comを削除してください
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3