Jest+React:如何在每次测试前重置location.href?
解决Jest测试中location.href无法重置的问题
可行方案1:用Jest Spy模拟并恢复location.href
在测试前后通过jest.spyOn配合属性重定义,实现location.href的修改与恢复,既能自定义URL参数,又不会破坏原有行为:
describe('你的组件测试', () => { let originalLocation; beforeEach(() => { // 保存原始location对象 originalLocation = window.location; // 重定义location为可写的URL实例 Object.defineProperty(window, 'location', { writable: true, value: new URL(originalLocation.href), }); }); afterEach(() => { // 恢复原始只读的location属性 Object.defineProperty(window, 'location', { writable: false, value: originalLocation, }); }); test('无URL参数时使用默认值', () => { window.location.href = 'http://localhost:3000/'; render(<YourComponent />); // 这里写你的断言逻辑,比如验证请求用了默认参数 }); test('有URL参数时使用参数值', () => { window.location.href = 'http://localhost:3000/?param=test'; render(<YourComponent />); // 这里写你的断言逻辑,比如验证请求用了传入的参数 }); });
可行方案2:重新配置jsdom的全局URL
Jest基于jsdom运行,直接修改jsdom的全局URL配置,避开window.location的只读限制:
describe('你的组件测试', () => { beforeEach(() => { // 重置jsdom的基础URL global.jsdom.reconfigure({ url: 'http://localhost:3000/', }); }); test('无参数时用默认值', () => { render(<YourComponent />); // 断言默认行为 }); test('带参数时使用参数', () => { // 临时修改为带参数的URL global.jsdom.reconfigure({ url: 'http://localhost:3000/?param=custom', }); render(<YourComponent />); // 断言参数生效的行为 }); });
为什么之前的方法会报错?
window.location.assign报错:jsdom默认只实现了hash变化的导航逻辑,完整页面跳转未被实现,所以调用assign会抛出"Not implemented: navigation (except hash changes)"错误。- 直接赋值
href或Object.defineProperty报错:jsdom中window.location被定义为只读属性,直接修改或重定义会触发"Cannot redefine property 'location'"错误。
为什么Jest默认不重置location.href?
Jest默认清理DOM是指清空document下的元素(比如body、div等),但window属于全局环境,Jest不会自动重置全局对象的属性——因为很多测试场景需要共享全局状态,自动重置会破坏这类需求。URL参数属于全局状态的一部分,因此需要开发者手动在测试钩子中处理重置逻辑。
内容的提问来源于stack exchange,提问作者Unapedra
相关产品推荐
相关产品推荐

