angularJS中的单元测试控制器

时间:2015-01-18 14:50:36

标签: angularjs unit-testing jasmine karma-runner karma-jasmine

我很难理解angularJs中的单元测试。我刚开始进行单元测试,语法对我来说似乎很奇怪。以下是测试controller

的代码
describe('PhoneCat controllers', function() {

  describe('PhoneListCtrl', function(){

    beforeEach(module('phonecatApp'));

    it('should create "phones" model with 3 phones',
    inject(function($controller) {
      var scope = {},
      ctrl = $controller('PhoneListCtrl', {$scope:scope});

      expect(scope.phones.length).toBe(3);
    }));

  });
});

从这种语法中我可以理解的是,在每个块之前,初始化phonecatApp并使用 $ controller 服务来获取PhoneListCtrl控制器的实例。

但是我无法理解这里的范围。有人可以详细说明在这条线上获得控制器范围的原因。

ctrl = $controller('PhoneListCtrl', {$scope:scope});

2 个答案:

答案 0 :(得分:1)

通常,在运行时,angular会创建一个范围并将其注入控制器函数以实例化它。 在单元测试中,您需要自己创建示波器并将其传递给控制器​​功能,以便能够在构建之后查看它是否确实有3个电话(例如)。

您可能还想将模拟服务而不是真实服务注入控制器。这就是对象数组允许的内容

$controller('PhoneListCtrl', {$scope:scope});

它告诉angular:创建一个名为'PhoneListCtrl'的控制器实例,但不是创建和注入一个范围,而是使用我给你的那个。

如果您的控制器依赖于服务'phoneService',并且您想要注入模拟phoneService,那么您可以

var mockPhoneService = ...;
$controller('PhoneListCtrl', { 
    $scope: scope,
    phoneService: mockPhoneService
});

答案 1 :(得分:1)

没有必要注入范围,你可以直接使用控制器的实例来调用控制器的功能和对象。在你的例子中你可以使用如下,这将给出相同的结果设为你的

describe('PhoneCat controllers', function() {

  describe('PhoneListCtrl', function(){

     beforeEach(module('phonecatApp'));

       it('should create "phones" model with 3 phones',
           inject(function($controller) {

      var ctrl = $controller('PhoneListCtrl');

  expect(ctrl.phones.length).toBe(3);
  }));

  });
});

并且每次控制器实例化时都会为您提供信息,它将绑定到$ scope变量,该变量派生自$ rootScope(即:roots的子项)。所以你需要传递$ scope来获取控制器的实例,我在上面的例子中做了同样的事情。