Maison >interface Web >js tutoriel >Récapitulatif de la plaisanterie : simulez en toute sécurité les propriétés et les méthodes des objets globaux
Dans un monde parfait base de code il n'est pas nécessaire de manipuler des objets globaux, mais le monde bases de code sont désordonnées - et donc est en train de tester.
Ce que vous voulez éviter à tout prix, c'est qu'un test affecte l'autre. Les tests doivent être significatifs quel que soit leur ordre ou si certains tests sont ignorés.
Une approche naïve des valeurs fictives consiste simplement à définir les propriétés sur la valeur dont vous avez besoin dans votre test.
C'est très bien tant que vous modifiez les valeurs des objets locaux appartenant (créés par) ce test spécifique :
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 vous faites cela pour des objets globaux, cela devient compliqué :
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); }); });
C'est pour cela que jest.replaceProperty() a été conçu :
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); }); });
Les méthodes peuvent être moquées de la même manière que les propriétés.
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 vous utilisez myObject.someFunction = jest.fn() sur des objets globaux, vos tests peuvent dépendre les uns des autres et perdre leur sens :
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); }); });
Comment devrions-nous nous moquer des méthodes dans les objets globaux ? C'est à cela que sert 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(); }); });
Si vous voulez être sûr que tous les tests trouvent le système dans le même état (frais, propre), vous devez restaurer l'état des simulations après chaque test.
La solution la plus simple consiste à définir la propriété de configuration restaurerMocks.
L'option la plus simple consiste à appeler jest.restoreAllMocks() dans afterEach()
Parfois, vous souhaitez vous moquer de choses pour tous les tests d'un fichier. Si vous utilisez jest.spyOn() et jest.replaceProperty() au niveau supérieur ou dans un bloc décrire(), tous les Mocks seront réinitialisés après l'exécution du premier test.
Au niveau supérieur, vous pouvez remplacer en toute sécurité les propriétés et les méthodes, sans jest.spyOn() et jest.replaceProperty().
Si vous souhaitez vous moquer d'éléments uniquement pour un bloc décrire(), vous devez effectuer ces appels dans un hook beforeEach().
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!