AngularJS+Karma-Jasmine单元测试遇UI Router相关意外请求错误
解决Karma-Jasmine测试AngularJS HTTP服务时的ui-router模板请求错误
我来帮你搞定这个头疼的问题!你遇到的Error: Unexpected request: GET app/license/license.html,本质是ui-router在测试初始化阶段自动触发了路由跳转,导致它去加载对应状态的模板文件,而你的$httpBackend没预料到这个额外的GET请求,所以抛出了错误。下面给你几个针对性的解决方案:
方案1:禁用ui-router的自动路由拦截
ui-router默认会在应用启动时自动处理路由,测试环境下我们可以关掉这个自动行为,让路由完全由我们手动控制:
beforeEach(module('yourAppModuleName', function($urlRouterProvider) { // 推迟ui-router的自动路由处理 $urlRouterProvider.deferIntercept(); }));
这样一来,测试初始化时就不会自动跳转到某个路由,也就不会触发模板的GET请求了。
方案2:用$httpBackend模拟模板请求
如果你的测试场景需要保留部分路由行为,或者不想禁用自动拦截,那可以直接让$httpBackend“预料到”这个模板请求,给它一个空响应就行:
beforeEach(inject(function($httpBackend) { // 先模拟模板请求,避免意外报错 $httpBackend.whenGET('app/license/license.html').respond(''); // 再写你原本要测试的HTTP请求模拟 $httpBackend.whenGET('/your/api/endpoint').respond({ key: 'value' }); })); // 测试用例里记得调用flush()触发响应 it('should fetch license data', inject(function($httpBackend, licensedataService) { licensedataService.getLicense().then(function(data) { expect(data).toEqual({ key: 'value' }); }); $httpBackend.flush(); // 触发所有模拟请求的响应 }));
方案3:检查licensedata.service是否隐含触发路由
你可以仔细看看licensedata.service的代码,有没有调用$state.go()、$transitionTo()这类会触发路由跳转的方法?或者依赖的其他服务里有这类逻辑?如果有的话,我们可以mock掉$state服务,避免它实际触发路由:
beforeEach(module('yourAppModuleName', function($provide) { // mock $state服务,替换掉原本的路由跳转方法 $provide.value('$state', { go: jasmine.createSpy('$state.go'), transitionTo: jasmine.createSpy('$state.transitionTo') }); }));
这样即使service里调用了路由方法,也只是触发一个spy,不会真的去加载模板。
你可以先从方案1或方案2开始试,这两个是最常见的解决办法。如果还是不行,把licensedata.service的具体代码贴出来,我们再进一步排查!
内容的提问来源于stack exchange,提问作者Ankit Prajapati
相关产品推荐
相关产品推荐

