在AngularJS中注入$ attrs

时间:2014-01-23 15:56:02

标签: angularjs unit-testing jasmine

我在AngularJS的上下文中编写了一些JavaScript。我的相关JavaScript如下所示:

.factory('$myFactory', function ($myLibrary, $interpolate) {
 return {
   myFunction: function ($scope, $attrs, p) {
     if (p !== null) {
       $attrs.set('myProperty', p);
     }
   }
 };

我正在尝试对此代码进行单元测试。为了对代码进行单元测试,我正在使用Jasmine。

it('should set myProperty', inject(function ($scope, $myFactory) {
//  $myFactory.myFunction($scope
}));

我无法弄清楚如何从我的单元测试中注入一些$ attrs。我怎么做?我可以成功获得我的$ scope设置。但是,我不明白如何注入$ attrs。我不知道有什么特别之处吗?我对$ element有类似的问题,尽管那个问题超出了这个特定测试的范围。

谢谢!

3 个答案:

答案 0 :(得分:9)

这是一个掠夺者:http://plnkr.co/edit/k1cxSjpAXhhJUEOcx9PG

也许有更好的解决方案,但这就是我得到的。

  • $scope很容易获得,您可以在任何地方注入$rootScope
  • 另一方面,
  • $attrs仅可通过$compile变量获取(它位于compile.js

我的解决方案是创建假控制器编译并劫持$attrs

这就是它的样子:

var injected = null

function fakeController($scope, $attrs, $element){
  injected = {}
  injected.$scope = $scope;
  injected.$attrs = $attrs;
  injected.$element = $element;
}

describe('Testing a Hello World controller', function() {
  var $scope = null;
  var $attrs = null;
  var $element = null;

  var ctrl = null;

  //you need to indicate your module in a test
  beforeEach(module('plunker'));

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

    $compile('<span ng-controller="fakeController"></span>')($rootScope);

    $scope = injected.$scope;
    $attrs = injected.$attrs;
    $element = injected.$element;

    ctrl = $controller('MainCtrl', {
      $scope: $scope,
      $attrs: $attrs,
      $element: $element
    });

  }));

  it('should say hallo to the World', function() {
    expect($scope.name).toEqual('World');
  });
});

答案 1 :(得分:5)

似乎你可以用空对象实例化控制器......

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

答案 2 :(得分:2)

在最新版本的AngularJS中,需要提供一个控制器才能获得完整的$ attrs。

请参阅$controllerProvider文档。

这是一个片段

describe('angular-component-controller', function() {

  // save injected parameters of controller
  var injected = {};
  var controller;

  // @see $https://docs.angularjs.org/api/ngMock/service/$componentController
  // we need to extract those from $compile instead of use as locals
  angular.module('locals', []).controller('controller',
    ['$attrs', function($attrs) {
      injected.$attrs = $attrs;
    }]
  );

  beforeEach(module('locals'));

  beforeEach(inject(function($rootScope, $compile, $componentController) {
    // invoke dummy component to get $attrs
    $compile('<span ng-controller="controller">')($rootScope);

    var locals = {};
    locals.$scope = $rootScope.$new();
    locals.$attrs = injected.$attrs;

    var bindings = {};

    controller = $componentController('component', locals, bindings);
  }));    
});

请参阅此要点AngularJS $componentController unit test