【问题标题】:Unit testing $rootScope.$$phase and $rootScope.$digest()单元测试 $rootScope.$$phase 和 $rootScope.$digest()
【发布时间】:2014-11-18 16:33:50
【问题描述】:

我的网站有

$rootScope.$broadcast('task1-completed', service.options.language);

然后调用

$rootScope.$on('task1-completed', function() {
    if (!$rootScope.$$phase) {
        $rootScope.$digest();
    }
});

单元测试适用于$broadcast$on,但我如何对内部函数进行单元测试? Aka make $rootScope.$$phase false 以便 $digest() 被调用...

我试图模拟整个 $rootScope 对象,但无法以这种方式工作。这更多是出于代码覆盖的目的,因为单元测试都运行良好。任何帮助表示赞赏!提前致谢!

【问题讨论】:

  • 什么是在没有$digest 的情况下发出 Angular 事件?您确定在您的生产代码中调用了$rootScope.$digest() ever 吗?
  • @DavinTryon 我不能 100% 确定这条特定的线路是否会在 prod 中被调用,但冗余不会伤害任何人,对吧?
  • 为什么要维护和测试从未使用过的代码?
  • @DavinTryon 比抱歉更安全。

标签: angularjs unit-testing jasmine chutzpah


【解决方案1】:

我只需将$on 更改为...即可解决此问题。

$scope.onUpdate = function() {
    if (!$rootScope.$$phase) {
        $rootScope.$digest();
    }
};

$rootScope.$on('task1-completed', function() {
    $scope.onUpdate();
});

这样我可以对 if 语句进行单元测试,而无需调用它的实际代码,这使得 $$phase 为 false 并确保调用 $digest()

【讨论】:

    【解决方案2】:

    Angular 中以$$ 为前缀的属性被视为私有成员,不可靠;它们是可能随时更改的实现细节。

    来自文档:https://docs.angularjs.org/api

    AngularJS 前缀 $ 和 $$:为了防止与您的代码发生意外的名称冲突,AngularJS 将公共对象的名称与 $ 和私有对象的名称与 $$...

    使用$scope.$evalAsync() 是一种安全且可接受的方法。

    Docs on $evalAsync

    一般来说,它不是在您拥有它的侦听指令中执行,而是在事件的原始代码中执行,这样就不需要在存在侦听器的任何地方复制它,这是一个好主意。

    $rootScope.$evalAsync(() => {
        $rootScope.$broadcast('task1-completed', service.options.language);
    })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-01
      • 2016-01-21
      相关资源
      最近更新 更多