構築中のAngularアプリをテストするためにKarmaをセットアップしようとしています。サービスとコントローラーに関するテストを既にセットアップしましたが、ディレクティブをテストするのがやや複雑であることがわかりました。
ディレクティブ:
angular.module('Directives',[])
.directive('tooltip', function factory(){
return {
link: {
post: function(scope, $element, instanceAttrs, controller){
$element.parent().append('<span class="tooltip-wrapper"><aside class="tooltip-container"></aside></span>');
var $tooltipWrapper = $element.next()
, $tooltip = angular.element($tooltipWrapper.children()[0]);
if(instanceAttrs.icon){
$tooltipWrapper.addClass('help icon standalone');
$element = $tooltipWrapper;
}
if(instanceAttrs.position){
$tooltip.addClass('tooltip-position-' + instanceAttrs.position);
} else {
$tooltip.addClass('tooltip-position-bottom-center');
}
if(instanceAttrs.position === 'right'){
$tooltipWrapper.addClass('tooltip-wrapper-right');
}
if(typeof instanceAttrs.message === 'undefined'){
$tooltip.html(instanceAttrs.$$element[0].childNodes[0].data);
$element.parent().children('tooltip').remove();
}
else {
$tooltip.html(instanceAttrs.message);
}
$tooltip.hide(); // <--- this is where the error gets thrown
$element.on('mouseover', goTooltip);
function goTooltip(){
$tooltip.show();
$element.on('mouseleave', killTooltip);
$element.off('mouseover');
}
function killTooltip(){
$tooltip.hide();
$element.off('mouseleave');
$element.on('mouseover', goTooltip);
}
}
},
scope: false,
replace: false,
restrict:'EA'
};
});
テスト:
describe("The tooltip", function(){
var elm
, scope;
beforeEach(module("RPMDirectives"));
beforeEach(inject(function($rootScope, $compile){
elm = angular.element(
'<div>' +
'<a></a>' +
'<tooltip icon="true" position="bottom-center-left">bar</tooltip>' +
'</div>' );
scope = $rootScope;
$compile(elm)(scope);
scope.$digest();
}));
it('should do something', inject(function($compile, $rootScope){
expect(elm.find('aside')).toBe('bar');
}))
});
テストを実行すると、Object [object Object] (ディレクティブのコメントで示される $tooltip) にはメソッド hide がないと表示されます。ディレクティブはブラウザで使用すると問題なく動作し、jqlite には確かに hide メソッドがあるため、途方に暮れています。テスト環境にjqueryを含めることで機能させることができると確信していますが、本番アプリでAngularを優先してjqueryを削除し、そのシナリオをここで証明する過程にあるので、それを行いたくありません重要です。