"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > Resumen de broma: propiedades y métodos simulados de objetos globales de forma segura

Resumen de broma: propiedades y métodos simulados de objetos globales de forma segura

Publicado el 2024-08-05
Navegar:731

Jest Recap: Safely Mock Properties and Methods of Global Objects

TL;DR:

  • Quieres evitar que las propiedades/métodos anulados/simulados afecten a otras pruebas.
  • Para objetos locales (creados y propiedad de esta prueba) puedes (y debes) usar
    • localObject.theAnswer = 42 y
    • localObject.calcTheAnswer = broma.fn(() => 42).
  • Para objetos globales debes usar
    • jest.replaceProperty(globalObject, "theAnswer", 42) y
    • jest.spyOn(globalObject, "calcTheAnswer").mockReturnValue(42).
  • Asegúrate de que se llame a jest.restoreAllMocks() en un gancho afterEach().

¿Qué?

En un mundo base de código perfecto no hay necesidad de manipular objetos globales, pero el mundo bases de código son ​​desordenados, y por eso está probando.

Lo que se quiere evitar a toda costa es que una prueba afecte a la otra. Las pruebas deben ser significativas independientemente de su orden o de si se omiten algunas pruebas.

Propiedades burlonas

Un enfoque ingenuo para los valores simulados es simplemente establecer las propiedades en cualquier valor que necesite en su prueba.
Esto está bien siempre que cambie los valores en los objetos locales que pertenecen (creados por) esta prueba específica:

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

Si haces eso para objetos globales, se vuelve complicado:

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



Para esto se creó 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);
    });
});

Métodos de burla

Se pueden burlar de los métodos de forma similar a las propiedades.

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

Si usa myObject.someFunction = jest.fn() en objetos globales, sus pruebas pueden depender unas de otras y perder su significado:

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



¿Cómo deberíamos burlarnos de los métodos en objetos globales? Para eso sirve 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();
    });
});

Debes limpiar

Si desea asegurarse de que todas las pruebas encuentren el sistema en el mismo estado (nuevo, limpio), debe restaurar el estado de las simulaciones después de cada prueba.

La solución más sencilla es establecer la propiedad de configuración de recoveryMocks.

La opción más sencilla es llamar a jest.restoreAllMocks() en afterEach()

Cómo burlarse de algo para todas las pruebas

A veces quieres simular cosas para todas las pruebas en un archivo. Si usa jest.spyOn() y jest.replaceProperty() en el nivel superior o en un bloque describe(), todos los simulacros se restablecerán después de ejecutar la primera prueba.

En el nivel superior puedes anular propiedades y métodos de forma segura, sin jest.spyOn() y jest.replaceProperty().

Si desea burlarse de cosas solo para un bloque describe(), debe realizar estas llamadas en un enlace beforeEach().

Declaración de liberación Este artículo se reproduce en: https://dev.to/htho/jest-recap-safely-mock-properties-and-methods-of-global-objects-3ph8?1 Si hay alguna infracción, comuníquese con Study_golang@163 .com para eliminarlo
Último tutorial Más>

Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.

Copyright© 2022 湘ICP备2022001581号-3