2

这是我提出的另一个问题的延续,该问题已成功回答。

我正在学习如何使用 Karma、Jasmine 和 ngMock 对 AngularJS 应用程序进行单元测试。这是我有疑问的代码:

describe('myController function', function() {

  describe('myController', function() {
    var scope;

    beforeEach(module('myApp'));

    beforeEach(inject(function($rootScope, $controller) {

      // These are the 2 lines I'm a bit confused about:
      scope = $rootScope.$new();
      $controller('MyController', {$scope: scope});

    }));

    it("...");
  });
});

问题1:为什么我们要新建一个scope并包含在locals注入区这一行:$controller('MyController', {$scope: scope});?它似乎工作得很好(例如,scope现在代表$scope来自该控制器的对象并具有它应该具有的所有属性和功能),但代码似乎暗示我们正在$scope用我们新创建的(并且为空的)重置控制器) scope(从行scope = $rootScope.$new();)。所以我想我只是没有完全理解那些当地人的目的/内部运作。

问题 2:从我的搜索中我也看到 newscope以两种常见的方式创建,或者上面显示的方式$rootScope.$new(),或者简单地声明scope = {}。甚至 Angular 文档都以两种方式进行,如此(使用) 和此处(使用 ) 所见。为什么这是一种方式而不是另一种方式?有区别吗?$rootScope.$new()$scope = {}

4

1 回答 1

3

为什么我们要创建一个新范围

有几个原因浮现在脑海中,但简短的回答是,如果您不想这样做,则不必这样做你可以很容易地通过$rootScope,你的测试仍然有效。它也只是通常完成,因为它更符合 angular 中实际发生的情况 -$scope注入控制器的可能是$rootScope.

什么是 $controller('MyController', {$scope: scope}); 正在做?

ngMock模块提供$controller函数作为创建控制器的一种构造函数——好吧,从技术上讲,它是模块中函数的装饰器,$controller但这ng并不重要。第一个参数通常是字符串,但也可以是函数。

如果用函数调用,那么它被认为是控制器构造函数。否则它被认为是一个用于检索控制器构造函数的字符串......

第二个参数是在创建期间注入控制器的“本地”。

所以,在你的例子中,你说你想创建“MyController”控制器,并且你想注入你的scope变量作为$scope控制器函数中命名的参数。

这样做的重点是将您自己的版本注入scope到控制器中,但是您在测试中创建的版本,以便您可以断言由于控制器而发生在范围内的不同事情。

这是依赖注入的好处之一。

例子

如果以下内容有意义:

var scope = {};
scope.add = function(){};
expect(typeof scope.add).toBe('function');

那么让我们更进一步,将函数的添加移到另一个函数中:

var addFunctionToScope = function(scope) {
  scope.add = function(){};
};
var scope = {};
addFunctionToScope(scope);
expect(typeof scope.add).toBe('function');

现在假设你的新函数将函数添加到范围实际上只是称为 $controller,而不是“addFunctionToScope”。

var scope = {};
$controller('SomeController', {$scope: scope});
expect(typeof scope.add).toBe('function');

为什么使用 $rootScope.$new() 而不是 {}

同样,您可以使用其中任何一个。但是,如果您计划使用某些特定于范围的函数,例如$on、 or $new、 or$watch等​​ - 您将需要注入一个实际的范围对象,该对象是在现有范围上使用 $new 函数创建的。

文档

于 2016-01-05T21:40:16.330 回答