当指令是属性时单元测试失败
Unit test failing when directive is an Attribute
我有一个声明为属性的指令:
app.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;
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');
});
});
但是,如果我将指令转换为元素,并删除替换和嵌入:
app.directive('myDirective', function() {
return {
restrict: 'E',
//replace: true,
//transclude: true,
scope: {
data: "="
},
template:
'<p class="my-paragrapgh">' +
'<label>Hello</label>' +
'</p>'
}
});
我的单元测试通过了:
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');
});
});
如何成功测试声明为属性的指令?我正在使用 Karma、Jasmine 和 PhantomJS
当您有 transclude: true
时,您需要在模板中的某个地方有一个 ng-transclude
,以便 angular 知道在哪里注入您的 HTML。尝试:
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>'
}
});
更新
看起来可能是 replace
选项导致了问题。
app.directive('myDirective', function() {
return {
restrict: 'A',
scope: {
data: "="
},
template:
'<p class="my-paragrapgh">' +
'<label>Hello</label>' +
'</p>'
}
});
replace: true
你内心 HTML 是:
失败
<label>Hello</label>
在 replace
未定义的情况下,您有
通过
<p class="my-paragrapgh"><label>Hello</label></p>
适用于 replace
和 transclude
,即使没有 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>
我有一个声明为属性的指令:
app.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;
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');
});
});
但是,如果我将指令转换为元素,并删除替换和嵌入:
app.directive('myDirective', function() {
return {
restrict: 'E',
//replace: true,
//transclude: true,
scope: {
data: "="
},
template:
'<p class="my-paragrapgh">' +
'<label>Hello</label>' +
'</p>'
}
});
我的单元测试通过了:
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');
});
});
如何成功测试声明为属性的指令?我正在使用 Karma、Jasmine 和 PhantomJS
当您有 transclude: true
时,您需要在模板中的某个地方有一个 ng-transclude
,以便 angular 知道在哪里注入您的 HTML。尝试:
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>'
}
});
更新
看起来可能是 replace
选项导致了问题。
app.directive('myDirective', function() {
return {
restrict: 'A',
scope: {
data: "="
},
template:
'<p class="my-paragrapgh">' +
'<label>Hello</label>' +
'</p>'
}
});
replace: true
你内心 HTML 是:
失败
<label>Hello</label>
在 replace
未定义的情况下,您有
通过
<p class="my-paragrapgh"><label>Hello</label></p>
适用于 replace
和 transclude
,即使没有 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>