Rumah  >  Artikel  >  hujung hadapan web  >  Jest Recap: Selamat Mengejek Sifat dan Kaedah Objek Global

Jest Recap: Selamat Mengejek Sifat dan Kaedah Objek Global

WBOY
WBOYasal
2024-07-19 15:10:32304semak imbas

Jest Recap: Safely Mock Properties and Methods of Global Objects

TL;DR:

  • Anda ingin mengelakkan sifat/kaedah yang ditindih/diejek menjejaskan ujian lain.
  • Untuk objek tempatan (dicipta dan dimiliki oleh ujian ini) anda boleh (dan harus) gunakan
    • localObject.theAnswer = 42 dan
    • localObject.calcTheAnswer = jest.fn(() => 42).
  • Untuk objek global yang anda patut gunakan
    • jest.replaceProperty(globalObject, "theAnswer", 42) dan
    • jest.spyOn(globalObject, "calcTheAnswer").mockReturnValue(42).
  • Pastikan jest.restoreAllMocks() dipanggil dalam cangkuk afterEach().

apa?

Dalam dunia pangkalan kod yang sempurna tidak perlu memanipulasi objek global, tetapi dunia pangkalan kod adalah berantakan - dan sebagainya sedang menguji.

Apa yang anda mahu elakkan pada semua kos, adalah untuk satu ujian menjejaskan yang lain. Ujian hendaklah bermakna tanpa mengira susunannya atau jika beberapa ujian dilangkau.

Sifat Mengejek

Pendekatan naif untuk mengejek nilai adalah dengan hanya menetapkan sifat kepada apa-apa nilai yang anda perlukan dalam ujian anda.
Ini tidak mengapa selagi anda menukar nilai dalam objek tempatan yang dimiliki (dicipta oleh) ujian khusus ini:

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

Jika anda berbuat demikian untuk objek global, ia akan menjadi kucar-kacir:

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

Ini adalah jest.replaceProperty() dibuat untuk:

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

Kaedah Mengejek

Kaedah boleh dipermainkan serupa dengan sifat.

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

Jika anda menggunakan myObject.someFunction = jest.fn() pada objek global, ujian anda mungkin bergantung antara satu sama lain dan kehilangan maknanya:

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

Bagaimanakah kita harus mengejek kaedah dalam objek global? Itulah kebaikan jest.spyOn() untuk:

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

Anda Mesti Bersihkan

Jika anda ingin memastikan semua ujian menemui sistem dalam keadaan yang sama (segar, bersih), anda perlu memulihkan keadaan olok-olok selepas setiap ujian.

Penyelesaian paling mudah ialah menetapkan sifat konfigurasi restoreMocks.

Pilihan ke hadapan yang paling lurus ialah memanggil jest.restoreAllMocks() dalam afterEach()

Cara Mengejek Sesuatu untuk semua Ujian

Kadangkala anda ingin mengejek sesuatu untuk semua ujian dalam fail. Jika anda menggunakan jest.spyOn() dan jest.replaceProperty() pada peringkat atas atau dalam blok describe(), semua Mocks akan ditetapkan semula selepas ujian pertama dilaksanakan.

Di peringkat teratas anda boleh mengatasi sifat dan kaedah dengan selamat, tanpa jest.spyOn() dan jest.replaceProperty().

Jika anda ingin mengejek sesuatu hanya untuk blok describe(), anda perlu membuat panggilan ini dalam cangkuk beforeEach().

Atas ialah kandungan terperinci Jest Recap: Selamat Mengejek Sifat dan Kaedah Objek Global. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel sebelumnya:Peta dalam JSArtikel seterusnya:Peta dalam JS