在 AngularJS 单元测试中模拟模块依赖
Posted
技术标签:
【中文标题】在 AngularJS 单元测试中模拟模块依赖【英文标题】:Mocking module dependencies in AngularJS unit tests 【发布时间】:2017-09-25 15:12:43 【问题描述】:我有一个 Angular 1.5 项目,其中包含许多模块,每个模块可能依赖于其他模块。尝试对作为模块一部分的控制器进行单元测试时,我会像这样导入模块:
angular.mock.module('SaidModule');
...然后在需要的地方提供并注入它的服务。
问题在于SaidModule
依赖于AnotherModule1
、AnotherModule2
、AnotherModule3
....
angular.module('SaidModule', ['AnotherModule1', 'AnotherModule2', 'AnotherModule3']);
所以很自然,当我调用 SaidModule 时,其他模块也会被调用,这超出了单元测试的范围
在单元测试中我尝试了以下解决方案
angular.module('AnotherModule1',[]);
angular.module('AnotherModule2',[]);
angular.module('AnotherModule3',[]);
angular.mock.module('SaidModule');
虽然对于当前的单元测试,我已经成功解耦了依赖关系,但我也销毁了 实际的 AnotherModule1、AnotherModule2、AnotherModule3 所以当轮到它进行单元测试时,它们是 在我看来正确的角度项目中甚至都看不到。因为我使用 angular.module 来定义一个 恰好覆盖实际模块的新模块。 不过,这里也建议使用此解决方案模拟模块依赖项
在 Angular 文档中,它指出请参阅 Angular 文档模拟模块 如果传递了一个对象文字,每个键值对将通过 $provide.value 在模块上注册, 键是与注入器上的值相关联的字符串名称(或标记)。
所以在我看来,解决方案以某种方式使用 angular.mock.module 以某种方式覆盖依赖项 模块,但到目前为止我还没有找到解决方案。 非常感谢任何帮助
【问题讨论】:
【参考方案1】:通过调用angular.module('AnotherModule1',[])
,您正在重新定义AnotherModule1
,我认为这会导致您的下游问题。相反,为每个依赖服务使用$provide
。无需模拟依赖模块。
假设您的控制器定义如下所示:
angular
.module('SaidModule', ['AnotherModule1', 'AnotherModule2'])
.controller('SaidController', [
'$scope',
'AnotherService',
function($scope, AnotherService)
this.anotherService = AnotherService.helper();
);
那么您的测试可能如下所示:
describe('SaidController', function()
var controller, scope, AnotherService;
beforeEach(module('SaidModule'));
beforeEach(module(function($provide)
AnotherService = helper: function() return 0; ;
$provide.value('AnotherService', AnotherService);
));
beforeEach(inject(function($controller, $rootScope)
scope = $rootScope.$new();
controller = $controller('SaidController',
$scope: scope
);
));
it('creates controller', function()
expect(controller).not.toBeNull();
);
);
无需模拟依赖模块,只需模拟依赖服务。
【讨论】:
虽然这似乎不起作用,但我不确定它的正确方法,因为当模块在这里运行时 beforeEach(angular.mock.module('SaidModule'));它会加载它的依赖模块,然后我会存根它们或之后的任何东西。我真正想做的是在我以某种方式调用 angular.mock.module 阶段时阻止它们被加载 也许这篇文章回答了你的问题:***.com/questions/17554727/… 感谢您的回复@mikwat,但我不同意上述解决方案。原因是当你测试一个单元时,你不应该关心外部世界发生了什么,但在这种情况下,他正在引入模块,为了不运行它的代码,他正在对它的所有服务和方法进行存根。如果你只有 1 个依赖的模块,它可能是一个临时解决方案,但我有 5 个依赖模块,因为该项目非常复杂,所以我不可能/毫无价值地去存根其他模块正在使用的每一个服务 我想不出任何方法来避免使用 javascript 或任何其他语言对依赖的服务和方法进行存根处理。 我想你误解了我的问题。服务和方法需要存根我完全同意,但我面临的问题是模块依赖关系,我找不到存根方法。例如,模块 A 依赖于模块 B 和 C,因此当我在单元测试中实例化模块 A 时,它自然也会运行模块 B 和 C。我相信解决方案是以某种方式使用 angular.mock.module “如果传递了一个对象文字,每个键值对将通过 $provide.value 在模块上注册,键是与喷油器上的值。”以上是关于在 AngularJS 单元测试中模拟模块依赖的主要内容,如果未能解决你的问题,请参考以下文章