测试angularjs指令(更改隔离范围var后模板未在测试中更新)

Dav*_*oro 1 javascript angularjs angularjs-directive

我正在创建一个angularjs组件,它将(将)提供一个带有过滤,排序,切换选项,滚动等的复选框列表指令......一旦完成.它应该可以帮助人们处理长复选框列表.

我正在尝试按标签或ID功能测试订单,但即使在$ digest或$ apply调用之后,模板也不会反映模型更改.我试图解决但没办法.

这是指令定义:

angular.module('angularjsSmartcheckboxApp')
  .directive('smartCheckbox', [function () {
    return {
      templateUrl: 'views/smartcheckbox.html',
      restrict: 'E',
      replace: true,
      scope: {model: '='},
      controller: ['$scope', '$element', '$attrs', function ($scope, $element, $attrs) {
        // TODO
      }]
    };
  }]);
Run Code Online (Sandbox Code Playgroud)

用法:

<smart-checkbox model="smartList" />
Run Code Online (Sandbox Code Playgroud)

其中smartList是:

$scope.smartList = [
    {id: '001', label: 'First item'},
    {id: '002', label: 'Second item'},
    {id: 'Z01', label: 'Another item'}
  ];
Run Code Online (Sandbox Code Playgroud)

这是模板:

...
<div class="input-group ordercontrols">
  Order options:
  <label class="radio-inline">
    <input type="radio" value="label" ng-model="orderby"> Label
  </label>
  <label class="radio-inline">
    <input type="radio" value="id" ng-model="orderby"> Id
  </label>
  <label>
    <input type="checkbox" ng-model="reverse" />
    Reverse
  </label>
</div>

<div>
  <div class="checkbox widgetcontrols" ng-repeat="elem in model | filter:{$:filter} | orderBy: orderby:reverse">
    <label>
      <input class="smart" type="checkbox" ng-model="elem.value" value="{{elem.value || false}}" />
      <span class="itemid">[{{elem.id}}]</span> {{elem.label}}
    </label>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

在这里你可以找到失败的测试'标签订单(反向)':

describe('Directive: smartCheckbox', function () {

  // load the directive's module
  beforeEach(module('angularjsSmartcheckboxApp', 'views/smartcheckbox.html'));

  var element,
    $rootScope,
    $compile,
    scope;

  beforeEach(inject(function (_$rootScope_, _$compile_) {
    $rootScope = _$rootScope_;
    scope = $rootScope.$new();
    $compile = _$compile_;
    $rootScope.model = [
        {id: '001', label:'First item'},
        {id: '002', label:'Second item'}
    ];

    element = $compile(angular.element('<smart-checkbox model="model"></smart-checkbox>'))(scope);
    $rootScope.$apply();

  }));

  it('Labels order (reverse)', function () {

    scope.reverse = true;
    scope.orderby = 'label';
    scope.$apply();

    expect(element.children().eq(3).find('label').eq(0).find('span').text()).toBe('[002]');
  });
});
Run Code Online (Sandbox Code Playgroud)

存储库链接:https: //github.com/davidemoro/angularjs-smartcheckbox

PS:如果你打开浏览器,重新排序工作正常,所以我认为测试方法有一些问题.

问题是什么?先感谢您

Dav*_*oro 5

我是如何解决的:

-    element = $compile(angular.element('<smart-checkbox model="model"></smart-checkbox>'))(scope);
+    $element = angular.element('<smart-checkbox model="model"></smart-checkbox>');
+    element = $compile($element)(scope);

...

   it('Labels order (reverse)', function () {

-    scope.reverse = true;
-    scope.orderby = 'label';
-    scope.$apply();
+    $element.isolateScope().reverse = true;
+    $element.isolateScope().orderby = 'label';
+    $element.isolateScope().$apply();

-    expect(element.children().eq(3).find('label').eq(0).find('span').text()).toBe('[002]');
+    expect($element.children().eq(3).find('label').eq(0).find('span').text()).toBe('[002]');
   });
Run Code Online (Sandbox Code Playgroud)

由于该指令使用隔离范围,我需要使用.isolateScope方法.希望它可以帮助其他人:)

更新:我根据这个答案写了一篇博客文章.见http://davidemoro.blogspot.com/2014/02/testing-angularjs-directives-with_13.html