В идеальном мире кодовой базе нет необходимости манипулировать глобальными объектами, но мир кодовые базы беспорядочен - и поэтому тестируется.
Чего следует избегать любой ценой, так это влияния одного теста на другой. Тесты должны быть значимыми независимо от их порядка или отсутствия некоторых тестов.
Наивный подход к имитации значений — просто установить для свойств любое значение, необходимое вам в тесте.
Это нормально, если вы меняете значения в локальных объектах, принадлежащих (созданных) этим конкретным тестом:
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); }); });
Если вы сделаете это для глобальных объектов, получится путаница:
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); //Вот для чего был создан 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); }); });Методы издевательств
Методы можно имитировать аналогично свойствам.
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(); }); });Если вы используете myObject.someFunction = jest.fn() для глобальных объектов, ваши тесты могут зависеть друг от друга и потерять свой смысл:
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(); //Как нам следует имитировать методы в глобальных объектах? Вот для чего хорош 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(); }); });Вы должны очиститься
Если вы хотите быть уверены, что все тесты находят систему в одном и том же (свежем, чистом) состоянии, вам необходимо восстанавливать состояние макетов после каждого теста.
Самое простое решение — установить свойство конфигурации restreMocks.
Самый простой вариант — вызвать jest.restoreAllMocks() в afterEach()
Как что-то имитировать для всех тестов
Иногда вам нужно замокать все тесты в файле. Если вы используете jest.spyOn() и jest.replaceProperty() на верхнем уровне или в блоке описания(), все Mocks будут сброшены после выполнения первого теста.
На верхнем уровне вы можете безопасно переопределять свойства и методы без jest.spyOn() и jest.replaceProperty().
Если вы хотите создавать макеты только для блока описания(), вам нужно выполнить эти вызовы в хуке beforeEach().
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3