Angular中@Inject(DOCUMENT)注入Document的单元测试及跳转报错问题求助
解决Angular测试中DOCUMENT注入与导航报错问题
错误原因解析
你遇到的Not implemented: navigation (except hash changes)错误,根源在于Jest使用的jsdom模拟浏览器环境不支持通过修改location.href触发页面跳转——它只实现了哈希变化的导航,完整的页面导航不在其模拟范围内。你之前直接注入全局document,调用cancel()时会触发jsdom不支持的导航逻辑,因此抛出错误。
解决方案
我们需要通过模拟DOCUMENT对象来避免触发真实导航,同时验证cancel()方法的行为是否符合预期:
1. 配置测试模块时注入模拟的DOCUMENT
修改TestBed.configureTestingModule中的providers,替换真实的document为自定义模拟对象:
beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ LinkIconeBradescoModule, RouterTestingModule, ModalMobileBradescoModule ], declarations: [BankSlipConfirmationComponent, ConfirmationModalComponent], providers: [ { provide: DOCUMENT, useValue: { location: { href: '' } // 初始化空href,后续可监听修改 } }, BankSlipInclusionService ] }).compileComponents(); }));
2. 编写验证逻辑的测试用例
在测试中获取模拟的DOCUMENT对象,验证cancel()是否正确设置了预期的URL:
it('should navigate to the menu URL when cancel button is clicked', () => { // 获取注入的模拟document const mockDocument = TestBed.inject(DOCUMENT); // 调用组件的cancel方法 component.cancel(); // 验证href是否被设置为环境变量中的菜单URL expect(mockDocument.location.href).toBe(environment.urlMenu); });
3. 扩展模拟(可选)
如果你的组件还用到了document的其他方法(比如querySelector、getElementById),可以在模拟对象中补充对应的模拟实现,例如:
{ provide: DOCUMENT, useValue: { location: { href: '' }, querySelector: jest.fn().mockReturnValue(null) } }
核心思路
通过依赖注入替换真实的document,我们可以完全控制测试环境中的DOM行为,既避免了jsdom不支持的导航操作,又能精准验证组件方法的逻辑是否正确——测试的核心是验证组件是否执行了正确的操作,而非真正跳转到目标页面。
内容的提问来源于stack exchange,提问作者Gustavo Rey
相关产品推荐
相关产品推荐

