使用外部模板测试组件(angularjs>;=1.5)
我想用一个外部模板测试一个组件。但是,每当我试图在组件中找到一个元素时,我都没有得到任何结果。看起来组件是空的 我加载模板的方式是否有问题,或者我是否正确编译了组件 项目结构:使用外部模板测试组件(angularjs>;=1.5),angularjs,unit-testing,karma-runner,Angularjs,Unit Testing,Karma Runner,我想用一个外部模板测试一个组件。但是,每当我试图在组件中找到一个元素时,我都没有得到任何结果。看起来组件是空的 我加载模板的方式是否有问题,或者我是否正确编译了组件 项目结构: libs/ app/ arc/ app.component.js app.module.js feature1/ A.component.js A.component.spec.js A.con
libs/
app/
arc/
app.component.js
app.module.js
feature1/
A.component.js
A.component.spec.js
A.controller.js
A.html
feature2/
B.component.js
B.component.spec.js
B.controller.js
B.html
karma.conf.js
//jshint strict: false
module.exports = function(config) {
config.set({
basePath: './src/app',
frameworks: ['jasmine'],
files: [
'../../libs/angular/angular.js',
'../../libs/angular-mocks/angular-mocks.js',
'../../libs/angular-ui-router/release/angular-ui-router.js',
'../../libs/angular-animate/angular-animate.js',
'../../libs/angular-resource/angular-resource.js',
'**/*.module.js',
'**/*.spec.js',
'**/*.html',
],
preprocessors: {
'**/*.html': ['ng-html2js'],
'**/!(*.mock|*.spec).js': ['coverage']
},
ngHtml2JsPreprocessor: {
// strip this from the file path
///stripPrefix: '',
cacheIdFromPath: function(filepath) {
let cacheId = filepath.split('/');
return cacheId[ cacheId.length - 1 ];
},
// create a single module that contains templates from all the files
moduleName: 'templates'
},
colors: true,
autoWatch: true,
browsers: ['Chrome'],
reporters: ["spec"],
specReporter: {
maxLogLines: 5, // limit number of lines logged per test
suppressErrorSummary: true, // do not print error summary
suppressFailed: false, // do not print information about failed tests
suppressPassed: false, // do not print information about passed tests
suppressSkipped: true, // do not print information about skipped tests
showSpecTiming: false, // print the time elapsed for each spec
failFast: true // test would finish with error when a first fail occurs.
}
});
};
var AComponent = {
templateUrl: './A.html',
controller: 'AController',
bindings: {
}
};
angular
.module('app')
.component('feature1', AComponent );
'use strict';
describe('Component: AComponent', function () {
beforeEach(module('app'));
beforeEach(module('templates'));
var element;
var component;
var scope;
beforeEach(inject(function($rootScope, $compile){
scope = $rootScope.$new();
element = angular.element('<feature1> </feature1>');
scope.$apply(function(){
$compile(element)(scope);
});
}));
it('should contain header element', function() {
console.log( element.find('header').length )
});
});
A.html
<header> test </header>
A.component.spec.js
//jshint strict: false
module.exports = function(config) {
config.set({
basePath: './src/app',
frameworks: ['jasmine'],
files: [
'../../libs/angular/angular.js',
'../../libs/angular-mocks/angular-mocks.js',
'../../libs/angular-ui-router/release/angular-ui-router.js',
'../../libs/angular-animate/angular-animate.js',
'../../libs/angular-resource/angular-resource.js',
'**/*.module.js',
'**/*.spec.js',
'**/*.html',
],
preprocessors: {
'**/*.html': ['ng-html2js'],
'**/!(*.mock|*.spec).js': ['coverage']
},
ngHtml2JsPreprocessor: {
// strip this from the file path
///stripPrefix: '',
cacheIdFromPath: function(filepath) {
let cacheId = filepath.split('/');
return cacheId[ cacheId.length - 1 ];
},
// create a single module that contains templates from all the files
moduleName: 'templates'
},
colors: true,
autoWatch: true,
browsers: ['Chrome'],
reporters: ["spec"],
specReporter: {
maxLogLines: 5, // limit number of lines logged per test
suppressErrorSummary: true, // do not print error summary
suppressFailed: false, // do not print information about failed tests
suppressPassed: false, // do not print information about passed tests
suppressSkipped: true, // do not print information about skipped tests
showSpecTiming: false, // print the time elapsed for each spec
failFast: true // test would finish with error when a first fail occurs.
}
});
};
var AComponent = {
templateUrl: './A.html',
controller: 'AController',
bindings: {
}
};
angular
.module('app')
.component('feature1', AComponent );
'use strict';
describe('Component: AComponent', function () {
beforeEach(module('app'));
beforeEach(module('templates'));
var element;
var component;
var scope;
beforeEach(inject(function($rootScope, $compile){
scope = $rootScope.$new();
element = angular.element('<feature1> </feature1>');
scope.$apply(function(){
$compile(element)(scope);
});
}));
it('should contain header element', function() {
console.log( element.find('header').length )
});
});
“严格使用”;
描述('Component:AComponent',函数(){
在每个(模块(“应用”)之前;
每个之前(模块(“模板”);
var元素;
var分量;
var范围;
beforeach(注入(函数($rootScope,$compile){
scope=$rootScope.$new();
元素=角度。元素(“”);
作用域$apply(函数(){
$compile(元素)(范围);
});
}));
它('应该包含头元素',函数(){
console.log(element.find('header')。长度)
});
});
好的,我想我可能有一个临时解决方案
问题是,通过检查$templateCache
,我实际上可以看到所有模板都已正确加载。然而,它们并没有作为编译过程的一部分被获取。因此,为了使其工作,我必须显式地为$compile()
方法设置模板
ngHtml2JsPreprocessor: {
cacheIdFromPath: function(htmlPath) {
let cacheId = htmlPath.split('/');
return './'+cacheId[ cacheId.length - 1 ];
},
// create a single module that contains templates from all the files
moduleName: 'templates'
},
这里的主要问题是,当模板名称更改时,我也必须更新规范文件
'use strict';
describe('Component: AComponent', function () {
beforeEach(module('app'));
beforeEach(module('templates'));
var element;
var scope;
beforeEach(inject(function($rootScope, $compile, $templateCache ){
scope = $rootScope.$new();
let template = $templateCache.get('A.html');
element = angular.element( '<feature1>'+template+'</feature1>' );
scope.$apply(function(){
$compile(element)(scope);
});
}));
it('should contain header element', function() {
var header = angular.element(element[0].querySelector('header'));
expect(header.length).not.toBe(0);
});
});
“严格使用”;
描述('Component:AComponent',函数(){
在每个(模块(“应用”)之前;
每个之前(模块(“模板”);
var元素;
var范围;
beforeach(注入函数($rootScope、$compile、$templateCache){
scope=$rootScope.$new();
让template=$templateCache.get('A.html');
元素=角度元素(“”+模板+“”);
作用域$apply(函数(){
$compile(元素)(范围);
});
}));
它('应该包含头元素',函数(){
var header=angular.element(元素[0]。querySelector('header');
expect(header.length).not.toBe(0);
});
});
正如@StanislavKvitash所指出的,模板URL必须与组件中定义的完全相同。在我的例子中,前导“/”导致在编译组件时无法解析模板
为了解决这个问题,我刚刚在cacheIdFromPath
方法的所有结果中添加了缺少的“/”
ngHtml2JsPreprocessor: {
cacheIdFromPath: function(htmlPath) {
let cacheId = htmlPath.split('/');
return './'+cacheId[ cacheId.length - 1 ];
},
// create a single module that contains templates from all the files
moduleName: 'templates'
},
删除最后一个s
以匹配打开的Tagah my bad,这只是一个输入错误。但不是真正的根本原因。我没有看到任何元素包含classstat
soelement.find('.stat')
将找到nothing@Alexus$templateCache
中的templateUrl
与组件定义中的templateUrl>相同吗?您是对的,templateUrl。似乎名称必须完全准确,因为它是在组件中定义的。必须将前导“/”添加到cacheIdFromPath
方法的所有结果中。