Reputation: 8663
I have a directive which is declared as an Attribute:
app.directive('myDirective', function() {
return {
restrict: 'A',
replace: true,
transclude: true,
scope: {
data: "="
},
template:
'<p class="my-paragrapgh">' +
'<label>Hello</label>' +
'</p>'
}
});
I have a unit test, which is failing:
describe('myDirective test', function () {
var scope, compile, element;
beforeEach(module('myModule'));
beforeEach(inject(function ($rootScope, $compile) {
scope = $rootScope.$new();
element = angular.element("<div my-directive></div>");
$compile(element);
scope.$digest();
}));
it('should have a my-paragrapgh class', function () {
expect($(element).find('p')[0]).toHaveClass('my-paragrapgh');
});
});
However, if i convert my diretive to an Element, and remove replace and transclude:
app.directive('myDirective', function() {
return {
restrict: 'E',
//replace: true,
//transclude: true,
scope: {
data: "="
},
template:
'<p class="my-paragrapgh">' +
'<label>Hello</label>' +
'</p>'
}
});
My unit test passes:
describe('myDirective test', function () {
var scope, compile, element;
beforeEach(module('myModule'));
beforeEach(inject(function ($rootScope, $compile) {
scope = $rootScope.$new();
element = angular.element("<my-directive></my-directive>");
$compile(element);
scope.$digest();
}));
it('should have a my-paragrapgh class', function () {
expect($(element).find('p')[0]).toHaveClass('my-paragrapgh');
});
});
How can i successfully test a directive declared as an Attribute? I'm using Karma, Jasmine and PhantomJS
Upvotes: 3
Views: 1380
Reputation: 7438
Works with replace
and transclude
even if there is no ng-trasclude
angular.module('myModule', [])
.directive('myDirective', function() {
return {
restrict: 'A',
replace: true,
transclude: true,
scope: {
data: "="
},
template: '<p class="my-paragrapgh">' +
'<label>Hello</label>' +
'</p>'
}
});
describe('myDirective test', function() {
var scope, compile, element;
// Even we can introduce our Jasmine custom matcher
beforeEach(function() {
jasmine.addMatchers({
toHaveCSSClass: function(util, customEqualityTesters) {
return {
compare: function(actual, expected) {
debugger;
var result = {};
result.pass = util.equals(actual.hasClass(expected), true, customEqualityTesters);
if (result.pass) {
result.message = "Expected " + actual + " to not have CSS class '" + expected + "'";
} else {
result.message = "Expected " + actual + " to have CSS class '" + expected + "'";
}
return result;
}
}
}
});
});
beforeEach(module('myModule'));
beforeEach(inject(function($rootScope, $compile) {
scope = $rootScope.$new();
element = angular.element("<div my-directive></div>");
$compile(element);
scope.$digest();
}));
it('has a my-paragrapgh class', function() {
expect(element.hasClass('my-paragrapgh')).toBeTruthy();
});
it('has a my-paragrapgh class - tested by custom matcher', function() {
expect(element).toHaveCSSClass('my-paragrapgh')
});
});
<link href="//safjanowski.github.io/jasmine-jsfiddle-pack/pack/jasmine.css" rel="stylesheet" />
<script src="//safjanowski.github.io/jasmine-jsfiddle-pack/pack/jasmine-2.0.3-concated.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular-mocks.js"></script>
Upvotes: 0
Reputation: 4862
You will need to have an ng-transclude
somewhere in your template when you have the transclude: true
so that angular will know where to inject your HTML. Try:
app.directive('myDirective', function() {
return {
restrict: 'A',
replace: true,
transclude: true,
scope: {
data: "="
},
template:
'<div ng-transclude><p class="my-paragrapgh">' +
'<label>Hello</label>' +
'</p></div>'
}
});
Update
Looks like it's the replace
option that could be causing the issue.
app.directive('myDirective', function() {
return {
restrict: 'A',
scope: {
data: "="
},
template:
'<p class="my-paragrapgh">' +
'<label>Hello</label>' +
'</p>'
}
});
With replace: true
you're inner HTML is:
Fails
<label>Hello</label>
With replace
undefined you have
Pass
<p class="my-paragrapgh"><label>Hello</label></p>
Upvotes: 1