„Wenn ein Arbeiter seine Arbeit gut machen will, muss er zuerst seine Werkzeuge schärfen.“ – Konfuzius, „Die Gespräche des Konfuzius. Lu Linggong“
Titelseite > Programmierung > Scherz-Rekapitulation: Eigenschaften und Methoden globaler Objekte sicher simulieren

Scherz-Rekapitulation: Eigenschaften und Methoden globaler Objekte sicher simulieren

Veröffentlicht am 05.08.2024
Durchsuche:632

Jest Recap: Safely Mock Properties and Methods of Global Objects

TL;DR:

  • Sie möchten vermeiden, dass überschriebene/verspottete Eigenschaften/Methoden andere Tests beeinflussen.
  • Für lokale Objekte (die von diesem Test erstellt wurden und ihm gehören) können (und sollten) Sie verwenden
    • localObject.theAnswer = 42 und
    • localObject.calcTheAnswer = jest.fn(() => 42).
  • Für globale Objekte sollten Sie verwenden
    • jest.replaceProperty(globalObject, "theAnswer", 42) und
    • jest.spyOn(globalObject, "calcTheAnswer").mockReturnValue(42).
  • Stellen Sie sicher, dass jest.restoreAllMocks() in einem afterEach()-Hook aufgerufen wird.

Was?

In einer perfekten Welt Codebasis besteht keine Notwendigkeit, globale Objekte zu manipulieren, aber die Welt Codebasen sind chaotisch – und so testet.

Was Sie unbedingt vermeiden möchten, ist, dass sich ein Test auf den anderen auswirkt. Tests sollten unabhängig von ihrer Reihenfolge oder davon, ob einige Tests übersprungen werden, aussagekräftig sein.

Spotteigenschaften

Ein naiver Ansatz für Scheinwerte besteht darin, die Eigenschaften einfach auf den Wert zu setzen, den Sie in Ihrem Test benötigen.
Dies ist in Ordnung, solange Sie Werte in lokalen Objekten ändern, die diesem spezifischen Test gehören (von ihm erstellt wurden):

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

Wenn Sie das für globale Objekte tun, wird es chaotisch:

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



Dafür wurde jest.replaceProperty() gemacht:

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

Spottmethoden

Methoden können ähnlich wie Eigenschaften verspottet werden.

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();
    });
});

Wenn Sie myObject.someFunction = jest.fn() für globale Objekte verwenden, hängen Ihre Tests möglicherweise voneinander ab und verlieren ihre Bedeutung:

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



Wie sollen wir Methoden in globalen Objekten verspotten? Dafür ist jest.spyOn() gut:

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();
    });
});

Sie müssen aufräumen

Wenn Sie sicherstellen möchten, dass alle Tests das System im gleichen (frischen, sauberen) Zustand finden, müssen Sie den Zustand der Mocks nach jedem Test wiederherstellen.

Die einfachste Lösung besteht darin, die Konfigurationseigenschaft „restoreMocks“ festzulegen.

Die einfachste Option ist der Aufruf von jest.restoreAllMocks() in afterEach()

So verspotten Sie etwas für alle Tests

Manchmal möchten Sie Dinge für alle Tests in einer Datei verspotten. Wenn Sie jest.spyOn() und jest.replaceProperty() auf der obersten Ebene oder in einem beschreiben()-Block verwenden, werden alle Mocks zurückgesetzt, nachdem der erste Test ausgeführt wurde.

Auf der obersten Ebene können Sie Eigenschaften und Methoden sicher überschreiben, ohne jest.spyOn() und jest.replaceProperty().

Wenn Sie Dinge nur für einen beschreiben()-Block verspotten möchten, müssen Sie diese Aufrufe in einem beforeEach()-Hook durchführen.

Freigabeerklärung Dieser Artikel ist abgedruckt unter: https://dev.to/htho/jest-recap-safely-mock-properties-and-methods-of-global-objects-3ph8?1 Bei Verstößen wenden Sie sich bitte an Study_golang@163 .com, um es zu löschen
Neuestes Tutorial Mehr>

Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.

Copyright© 2022 湘ICP备2022001581号-3