"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Jest Recap: Propriedades e métodos simulados com segurança de objetos globais

Jest Recap: Propriedades e métodos simulados com segurança de objetos globais

Publicado em 2024-08-05
Navegar:918

Jest Recap: Safely Mock Properties and Methods of Global Objects

DR:

  • Você deseja evitar que propriedades/métodos substituídos/simulados afetem outros testes.
  • Para objetos locais (criados e pertencentes a este teste) você pode (e deve) usar
    • localObject.theAnswer = 42 e
    • localObject.calcTheAnswer = jest.fn(() => 42).
  • Para objetos globais você deve usar
    • jest.replaceProperty(globalObject, "theAnswer", 42) e
    • jest.spyOn(globalObject, "calcTheAnswer").mockReturnValue(42).
  • Certifique-se de que jest.restoreAllMocks() seja chamado em um gancho afterEach().

O que?

Em um mundo codebase não há necessidade de manipular objetos globais, mas o mundo codebases são confusos - e assim está testando.

O que você deseja evitar a todo custo é que um teste afete o outro. Os testes devem ser significativos independentemente de sua ordem ou se alguns testes forem ignorados.

Propriedades de simulação

Uma abordagem ingênua para valores simulados é apenas definir as propriedades para qualquer valor que você precisar em seu teste.
Isso é bom, desde que você altere os valores nos objetos locais pertencentes (criados por) este teste específico:

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

Se você fizer isso para objetos globais, ficará confuso:

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 isso que jest.replaceProperty() foi feito:

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 zombaria

Os métodos podem ser simulados de forma semelhante às propriedades.

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

Se você usar myObject.someFunction = jest.fn() em objetos globais, seus testes podem depender uns dos outros e perder o 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(); // 



Como devemos simular métodos em objetos globais? É para isso que jest.spyOn() é bom:

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

Você deve limpar

Se quiser ter certeza de que todos os testes encontrarão o sistema no mesmo estado (fresco, limpo), será necessário restaurar o estado das simulações após cada teste.

A solução mais simples é definir a propriedade de configuração restoreMocks.

A opção mais direta é chamar jest.restoreAllMocks() no afterEach()

Como simular algo para todos os testes

Às vezes você deseja simular coisas para todos os testes em um arquivo. Se você usar jest.spyOn() e jest.replaceProperty() no nível superior ou em um bloco subscribe(), todos os Mocks serão redefinidos após a execução do primeiro teste.

No nível superior, você pode substituir propriedades e métodos com segurança, sem jest.spyOn() e jest.replaceProperty().

Se você quiser simular coisas apenas para um bloco description(), você precisa fazer essas chamadas em um gancho beforeEach().

Declaração de lançamento Este artigo foi reproduzido em: https://dev.to/htho/jest-recap-safely-mock-properties-and-methods-of-global-objects-3ph8?1 Se houver alguma violação, entre em contato com study_golang@163 .com para excluí-lo
Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3