You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:51:16