最佳实践:单元测试中的$ rootScope或child $ scope?

gle*_*tre 10 unit-testing angularjs karma-runner

我在我的单元测试中使用基本模式(使用karma/jasmine运行)用于我的角度组件,我无法确定我的解决方案是否比我的同事建议的解决方案更安全或过度:

TL; DR:在单元测试中直接使用$ rootScope的优点/缺点是什么(仅限!)?

这是我目前的模式:

describe('component', function() {
  var $scope;

  beforeEach(module('myModule'));

  beforeEach(inject(function($rootScope) {
    $scope = $rootScope.$new();
    //working with it now
    $scope.foo = 'fooValue';
    $scope.$digest();
  }));

  afterEach(function() {
    $scope.$destroy();
  });

  describe('subcomponent', function() {
    it('should do something', function() {
      //arrange
      //act
      //assert
    });
  });
});
Run Code Online (Sandbox Code Playgroud)

我的同事建议使用:

$scope = $rootScope;
Run Code Online (Sandbox Code Playgroud)

代替

$scope = $rootScope.$new();
Run Code Online (Sandbox Code Playgroud)

会更简单,没有副作用,因为在每个规格之前inject创建一个新的$injector,提供一个新的和干净的$rootScope.

那么,这两种解决方案的好处/风险可能是什么?

Nota bene:在我们的应用程序中,我们总是避免$rootScope直接使用.

Gil*_*man 10

$rootScope在大多数情况下,直接测试应该可以正常工作.但是,如果您正在测试的组件注入,$rootScope则会发生以下奇怪现象:

  • 如果您正在测试指令,那么: element.scope() === $rootScope
  • 如果您正在测试控制器,那么: $scope === $rootScope

(假设你不嘲笑,以上情况属实$rootScope).始终通过$rootScope.$new()您正在进行的方式实例化子范围是一种安全措施,其实施成本很低.

还要记住,$rootScope并且$rootScope.$new()不是同一类的实例,尽管在实践中这似乎不是单元测试中的问题......

$rootScope对象:

$ rootScope

$rootScope.$new()以下内容创建的子范围对象:

$ rootScope.$新的()

$rootScope.$new(true)以下内容创建的子隔离范围对象:

$ rootScope.$新的(真正)

  • @glepretre,另一种陈述它的方法是如果你编译这样的指令:`elm ='<div directive> </ div>'; $ compile(elm)($ rootScope)`,然后在指令的链接函数中,`$ rootScope === element.scope()`将永远为真. (2认同)