Angular测试报错:href不可配置及代码未覆盖问题求助
解决Angular组件测试中的window.location.href报错与代码覆盖问题
问题分析
- 测试报错原因:
window.location.href是浏览器原生的不可配置属性,直接用spyOnProperty监听其setter会触发href is not declared configurable错误。 - 代码未覆盖原因:测试用例执行失败,导致
window.location.href = this.pingSAMLreqURL;这行代码从未被实际执行,因此未被覆盖率统计工具标记为已覆盖。
解决方案
修改测试用例,模拟window.location
通过临时替换window.location为可配置的模拟对象,绕过原生属性的限制,同时验证跳转逻辑:
it('should redirect to SAML login URL when onSamlLoginClick is called', () => { // 保存原始window.location,测试完成后恢复 const originalLocation = window.location; try { // 创建模拟location对象,包含可读写的href属性 const mockLocation = { href: '' }; Object.defineProperty(window, 'location', { writable: true, value: mockLocation }); // 执行组件方法 component.onSamlLoginClick(); // 验证href被设置为正确的SAML地址 expect(window.location.href).toBe(environment.samlURL); } finally { // 恢复原始window.location,避免影响其他测试 Object.defineProperty(window, 'location', { writable: true, value: originalLocation }); } });
验证代码覆盖
修改完成后重新执行ng test --coverage:
- 测试用例会正常执行
window.location.href = this.pingSAMLreqURL;这行代码,覆盖率工具会标记该行为已覆盖。 - 之前的报错会消失,测试用例将通过。
额外优化建议
如果后续需要多次测试window.location相关逻辑,可以将模拟与恢复逻辑封装成测试辅助函数,减少重复代码:
function mockWindowLocation(): () => void { const originalLocation = window.location; const mockLocation = { href: '' }; Object.defineProperty(window, 'location', { writable: true, value: mockLocation }); return () => Object.defineProperty(window, 'location', { writable: true, value: originalLocation }); } // 在测试中使用 it('should redirect to SAML login URL when onSamlLoginClick is called', () => { const restoreLocation = mockWindowLocation(); try { component.onSamlLoginClick(); expect(window.location.href).toBe(environment.samlURL); } finally { restoreLocation(); } });
内容的提问来源于stack exchange,提问作者Ruchi
相关产品推荐
相关产品推荐

