如何在Jasmine 3.6中模拟angular.element(document).injector().get('$location')
在Jasmine 3.6.0中模拟AngularJS $location的方案
针对你在Angular混合应用中通过angular.element(document).injector().get('$location')获取AngularJS导航服务,却无法在Jasmine中模拟的问题,直接给你可落地的模拟方案:
第一步:创建模拟的$location实例
先定义一个包含你业务中用到的导航方法的mock对象,比如常用的path、url、replace:const mockLocation = jasmine.createSpyObj('$location', ['path', 'url', 'replace']);第二步:完整拦截调用链
你的代码是链式调用angular.element(document).injector().get('$location'),所以需要逐层mock每个环节,确保组件拿到的是我们的mock对象。在测试的beforeEach块中添加:beforeEach(() => { // 模拟angular.element(document)返回的对象 const mockAngularElement = { injector: jasmine.createSpy('injector').and.returnValue({ get: jasmine.createSpy('get').and.callFake(serviceName => { if (serviceName === '$location') { return mockLocation; } // 若组件还依赖其他AngularJS服务,可在此扩展返回对应的mock return null; }) }) }; // 替换全局angular对象的element方法 spyOn(angular, 'element').and.returnValue(mockAngularElement); // 初始化组件(确保mock完成后再实例化组件) TestBed.configureTestingModule({ declarations: [YourComponent] }).compileComponents(); fixture = TestBed.createComponent(YourComponent); component = fixture.componentInstance; fixture.detectChanges(); });第三步:验证导航行为
触发组件中的导航逻辑后,直接断言mock对象的方法调用情况:it('should navigate to target AngularJS route', () => { // 调用组件内的导航方法 component.goToAngularJsPage(); // 断言path方法被传入正确的路由参数 expect(mockLocation.path).toHaveBeenCalledWith('/angularjs-target-route'); });额外处理:解决TypeScript类型报错
如果测试环境未加载AngularJS,需在测试文件顶部声明全局angular变量:declare const angular: any;
注意:一定要确保mock逻辑在组件实例化前执行,否则组件会拿到真实的injector(如果存在的话),导致mock失效。之前Stack Overflow的方案可能只覆盖了部分调用环节,这个完整的链式mock应该能解决你的问题。
内容的提问来源于stack exchange,提问作者zen zen
相关产品推荐
相关产品推荐

