
长话短说:
您希望避免覆盖/模拟的属性/方法影响其他测试。对于本地对象(由该测试创建并拥有),您可以(并且应该)使用localobject.theanswer = 42 和localobject.calctheanswer = jest.fn(() => 42).对于全局对象,您应该使用jest.replaceproperty(globalobject, “theanswer”, 42) 和 jest.spyon(globalobject, “calctheanswer”).mockreturnvalue(42).确保在 aftereach() 钩子中调用 jest.restoreallmocks() 。
什么?
在完美的世界代码库中,不需要操作全局对象,但是世界代码库很混乱 – 测试也是如此。
您要不惜一切代价避免一个测试影响另一个测试。无论顺序如何,或者是否跳过某些测试,测试都应该有意义。
模拟属性
模拟值的一种简单方法是将属性设置为测试中所需的任何值。
只要您更改此特定测试拥有(创建)的本地对象中的值就可以了:
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); // <-- error: expect(received).tobegreaterthan(expected) }).tothrow(error); });});
这就是 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(); // <-- error: expect(received).tobenull() }).tothrow(error); });});
我们应该如何模拟全局对象中的方法?这就是 jest.spyon() 的好处:
智谱清言 – 免费全能的AI助手
智谱清言 – 免费全能的AI助手
2 查看详情
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(); });});
你必须清理
如果你想确保所有测试都发现系统处于相同(新鲜、干净)状态,则需要在每次测试后恢复模拟的状态。
最简单的解决方案是设置restoremocks配置属性。
最直接的选择是在 aftereach() 中调用 jest.restoreallmocks()
如何为所有测试模拟某些内容
有时您想模拟文件中所有测试的内容。如果您在顶层或在describe()块中使用jest.spyon()和jest.replaceproperty(),则在执行第一个测试后,所有mock将被重置。
在顶层,您可以安全地重写属性和方法,无需 jest.spyon() 和 jest.replaceproperty()。
如果您只想为describe() 块模拟事物,则需要在beforeeach() 挂钩中进行这些调用。
以上就是笑话回顾:安全模拟全局对象的属性和方法的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/470003.html
微信扫一扫
支付宝扫一扫