0

I have the following directive:

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;
        }
    };
}

It uses this template:

<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>

notice on line 19 there's another angular directive.

Everything works fine in the app but my unit tests for InfoList Directive started failing when I added this kobocat-form-publisher directive to the template. How can I mock this directive for the purpose of getting the InfoList directive tests passing again?

2 Answers 2

1

I've never tried mocking a directive before, but I would think this works

(assuming Jasmine)

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

Given that it works, you'll still have to have a mock implementation which you probably don't want to have sitting in production code which you would need to have loaded into the module. That's the part I'm not 100% sure will work, you might have to declare the directive inline.

On a sidenote, if it's a unit test I assume you're compiling the directive inside the test, in which case a more pragmatic solution is to just remove the external directive from the HTML before compiling it.

Sign up to request clarification or add additional context in comments.

3 Comments

Yes, that might work. Since it's a directive inside a directive I'm not declaring the directive I want to mock out inside my test, but I could transform the directive's template before compiling it. I'll give it a try, tell you how it went. Thanks!
Yes, that worked. I ended up doing $templateCache.put('templates/InfoList.Template.html', $templateCache.get('templates/InfoList.Template.html').replace('kobocat-form-publisher', '')) in my beforeEach method. Thanks for pointing me in the right direction!
I still think the $provide approach would also work, but the replace is a lot less work :)
0

As stated by this answer to this question ("How do you mock directives..."), the 'correct' way is to use the $compileProvider service. The solution in short: It allows you to declare a directive with the same name but higher priority than your original directive. Setting terminal: true prevents your original directive from being compiled.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.