外部テンプレートを使用し、サービスからデータが渡されるカスタム ディレクティブがあります。データを変更する前に約束が解決されていることを確認することにしました。これは実際のコードでは問題ありませんでしたが、単体テストが壊れてしまい、面倒でした。私はいくつかのバリエーションを試しましたが、今は立ち往生しています。「ng-html2js」プリプロセッサを使用しています。
単体テストはこちら
describe('ccAccordion', function () {
var elm, scope, deferred, promise, things;
beforeEach(module('ccAccordion'));
// load the templates
beforeEach(module('components/accordion/accordion.html'));
beforeEach(inject(function ($rootScope, $compile, $q) {
elm = angular.element(
'<cc-accordion items="genres"></cc-accordion>'
);
scope = $rootScope;
things = [{
title: 'Scifi',
description: 'Scifi description'
}, {
title: 'Comedy',
description: 'Comedy description'
}];
deferred = $q.defer();
promise = deferred.promise;
promise.then(function (things) {
scope.items = things;
});
// Simulate resolving of promise
deferred.resolve(things);
// Propagate promise resolution to 'then' functions using $apply().
scope.$apply();
// compile the template?
$compile(elm)(scope);
scope.$digest();
}));
it('should create clickable titles', function () {
var titles = elm.find('.cc-accord h2');
expect(titles.length).toBe(2);
expect(titles.eq(0).text().trim()).toBe('Scifi');
expect(titles.eq(1).text().trim()).toBe('Comedy');
});
カスタム addMatchers と残りのテストは省略しました。私が得るエラーは
TypeError: 'undefined' is not an object (evaluating 'scope.items.$promise')
ここにディレクティブがあります
var ccAccordion = angular.module("ccAccordion", []);
ccAccordion.directive("ccAccordion", function () {
return {
restrict: "AE",
templateUrl: "components/accordion/accordion.html",
scope: {
items: "="
},
link: function (scope) {
scope.items.$promise.then(function (items) {
angular.forEach(scope.items, function (item) {
item.selected = false;
});
items[0].selected = true;
});
scope.select = function (desiredItem) {
(desiredItem.selected === true) ? desiredItem.selected = false : desiredItem.selected = true;
angular.forEach(scope.items, function (item) {
if (item !== desiredItem) {
item.selected = false;
}
});
};
}
};
});
これは、ディレクティブが main.html で使用される場所です。
<cc-accordion items="genres"></cc-accordion>
メインコントローラーでは、ジャンルサービスが渡されます
angular.module('magicApp')
.controller('GenresCtrl', ['$scope', 'BREAKPOINTS', 'Genre',
function ($scope, BREAKPOINTS, Genre) {
$scope.bp = BREAKPOINTS;
$scope.genres = Genre.query();
}]);