如何在Jasmine单元测试中Mock Angular指令的依赖?
解决Angular指令测试中的$injector:modulerr错误
咱们先拆解下问题核心:你的myApp模块声明时依赖的是整个services.FuzzAPI模块,但你之前的测试直接尝试mock单个服务,Angular在初始化myApp时找不到它依赖的services.FuzzAPI模块,所以抛出了$injector:modulerr错误——这也是你inject里的console.log没触发的原因:模块加载失败后,测试直接跳过了inject阶段。
修复步骤
1. 先创建Mock的services.FuzzAPI模块
因为原模块依赖的是模块而非单个服务,所以我们得先定义一个mock版本的services.FuzzAPI模块,在里面提供我们需要的FuzzAPI服务(注意原指令注入的是FuzzAPI,不是带模块前缀的services.FuzzAPI):
beforeEach(function(){ // 首先创建mock的services.FuzzAPI模块,和原依赖的模块名完全一致 angular.module('services.FuzzAPI', []) .service('FuzzAPI', function() { // 模拟原FuzzAPI的核心方法,适配测试需求 this.initializeCurrentItem = function() { return true; }; // 把事件回调存起来,方便后续测试手动触发事件 this.onDataEvent = function(eventName, callback) { this._eventCallback = callback; }; this.unregister = function() { // 模拟注销逻辑,空实现也满足测试需求 }; }); // 现在加载myApp模块,它依赖的services.FuzzAPI已经存在了 angular.mock.module('myApp'); });
2. 调整Inject阶段的代码
模块依赖问题解决后,inject阶段就能正常执行了。我们可以获取mock的FuzzAPI实例,方便后续测试逻辑编写:
beforeEach(inject(function($rootScope, _$compile_, _FuzzAPI_) { console.log("in inject.."); $scope = $rootScope.$new(); $compile = _$compile_; // 拿到mock的FuzzAPI服务实例,后续测试可以用它触发事件 this.FuzzAPI = _FuzzAPI_; // 编译指令并触发digest更新视图 element = $compile("<my-app></my-app>")($scope); $scope.$digest(); }));
3. 添加测试用例示例
现在可以编写实际的测试逻辑了,比如测试初始值、事件触发后的视图变化:
it('should initialize with "Hello World" greeting', function() { expect($scope.greeting).toBe('Hello World'); }); it('should update greeting when onFuzzEvent is triggered', function() { // 调用mock服务里存的回调,模拟事件触发 this.FuzzAPI._eventCallback('Mocked Fuzz Data'); // 触发digest更新视图和scope $scope.$digest(); expect($scope.greeting).toBe('Mocked Fuzz Data'); });
额外需要处理的细节
- 模板加载问题:原指令的
templateUrl依赖localStorage.getItem("baseURL"),测试环境下这个值大概率不存在,会导致模板加载失败。可以用$templateCache提前缓存模板:beforeEach(function(){ // ... 其他mock代码 angular.mock.module(function($provide) { $provide.value('$templateCache', { get: function() { // 返回你的指令模板HTML字符串,比如: return '<div>{{greeting}}</div>'; } }); }); }); - 服务注入名称:确保mock的服务名称和原指令注入的名称完全一致(原代码里是
FuzzAPI,不是services.FuzzAPI),否则会出现注入失败的问题。
内容的提问来源于stack exchange,提问作者Brian Var
相关产品推荐
相关产品推荐

