模拟AngularJS指令

时间:2014-06-21 16:09:44

标签: angularjs unit-testing angularjs-directive mocking

我有以下指令:

function InfoListDirective($rootScope, $restApi) {
    return {
        restrict: 'A',
        templateUrl: staticFilesUri + 'templates/InfoList.Template.html',
        scope: {
            items: '=',
            refreshItemList: '&',
            canAddNew: '@',
            name: '@',
            linkTo: '@',
            deleteItem: '&',
            canDelete: '@'
        },
        link: function (scope) {
            scope.kobocatLinkExists = function (item) {
                return window.koboConfigs && window.koboConfigs.kobocatServer;
            };


            scope.getHashLink = function (item) {
                var linkTo = scope.linkTo;
                return linkTo ? '/' + linkTo + '/' + item.id : '';
            };

            scope.getLink = function (item, format) {
                if(!format) {
                    format = "xml";
                }
                return scope.name.toLowerCase() + '/' + item.id + "?format=" + format;
            };

            scope.canDelete = scope.canDelete === 'true';
            $rootScope.canAddNew = scope.canAddNew === 'true';

            $rootScope.activeTab = scope.name;
        }
    };
}

它使用此模板:

<header class="forms-header">
  <div class="container">
    <h1 class="forms-header__title">Form Drafts</h1>
    <a href="#/builder" class="forms-header__button">+ Add Form</a>
  </div>
</header>
<div class="container">
  <div class="forms-filter">
    <div class="forms-filter__search">
      <i class="fa fa-search"></i> <input class="forms-filter__searchbox" placeholder="Search forms"  ng-model="searchCriteria" />
    </div>
    <select class="forms-filter__sorter">
      <option>Sort</option>
    </select>
  </div>

  <div class="info-list">
      <div class="forms__card" ng-repeat="item in items|orderBy:'-date_modified'">
        <div kobocat-form-publisher class="forms__card__kobocat" item="item" ng-show="kobocatLinkExists()">

        </div>
        <div class="forms__card__info">
          <a class="forms__card__title" href="#{{ getHashLink(item) }}">{{ item.name }}</a>
          <p class="forms__card__description">{{ item.description || '' }}</p>
          <p class="forms__card__date">
            {{item.date_modified.getMonth()+1}}/{{item.date_modified.getDate()}}/{{item.date_modified.getYear() + 1900}}
          </p>
          <p class="forms__card__question-count">
            {{ item.rowCount }}
          </p>
        </div>
        <div class="forms__card__buttons">
          <a class="forms__card__buttons__button blue" href="{{ getLink(item, 'xml') }}"><i class="fa fa-copy"></i></a>
          <a class="forms__card__buttons__button gray" href="{{ getLink(item, 'xls') }}"><i class="fa fa-download"></i></a>
          <a class="forms__card__buttons__button red" href="" ng-click="deleteItem({item: item})"><i class="fa fa-trash-o"></i></a>
        </div>
      </div>
  </div>


</div>

第19行注意到另一个角度指令。

应用程序中的一切正常,但是当我将InfoList指令添加到模板时,kobocat-form-publisher指令的单元测试开始失败。为了让InfoList指令测试再次通过,我该如何模拟这个指令呢?

2 个答案:

答案 0 :(得分:1)

我之前从未尝试过嘲笑指令,但我认为这有效

(假设Jasmine)

beforeEach(module('yourModuleName', function($provide) {
    var yourMock = $provide.value('yourMockDirective');
    $provide.value('kobocatFormPublisherDirective', yourMock);
});

鉴于它的工作原理,您仍然需要一个模拟实现,您可能不希望将其置于生产代码中,您需要将其加载到模块中。这是我不是100%肯定会工作的部分,你可能必须内联声明该指令。

在旁注中,如果它是单元测试,我假设您正在编译测试中的指令,在这种情况下,更实用的解决方案是在编译之前从HTML中删除外部指令。

答案 1 :(得分:0)

正如this answerthis question所述(“你如何模拟指令......”),“正确”的方法是使用$compileProvider服务。简而言之:它允许您声明一个具有相同名称但优先级高于原始指令的指令。设置终端:true可防止编译原始指令。