我正在尝试在我的Ember应用程序单元测试中测试一个组件,直到现在一切都很好,除了我处于断言需要渲染模板的位置。
这样做通常可以打电话给
var comp = App.SomeNamedComponent.create();
var comp.appendTo(App.rootElement);
但是虽然这确实创建了组件的基本元素,但它不会呈现其模板。经过一些研究后,我最终发现组件上没有设置templateName
和template
属性。所以我决定自己设置templateName
,但后来抱怨A Component must have a parent view in order to yield.
。
然后我决定使用该组件在模板中创建另一个自定义视图,但后来我无法访问该组件的实例......
我需要访问实例来进行断言,我需要渲染它的模板,因为某些属性是根据模板中某些元素的css计算的。
答案 0 :(得分:20)
这就是我通常在不需要容器时测试组件的方式(特别是当以编程方式向组件提供模板和布局时):
Ember.testing = true;
MyAwesomeComponent = Ember.Component.extend();
function createComponent(componentName, factory, options) {
if (typeof options.template === 'string') {
options.template = Ember.Handlebars.compile(options.template);
}
if (typeof options.layout === 'string') {
options.layout = Ember.Handlebars.compile(options.layout);
}
if (options.template && !options.layout) {
options.layout = options.template;
delete options.template;
}
var component = factory.create(options);
Ember.run(function(){
component.appendTo('#qunit-fixture');
});
return component;
}
module('component testing sample');
test('a component with template', function(){
var options = {layout: 'woot woot{{fullName}}'};
var component = createComponent('my-awesome', MyAwesomeComponent, options);
equal(component.$().text(), 'woot woot');
});
test('a component with custom options and a template', function(){
var options = {
fullName: 'Robert Jackson',
layout: '{{fullName}}'
};
var component = createComponent('my-awesome', MyAwesomeComponent, options);
equal(component.$().text(), 'Robert Jackson');
});
查看示例JSBin。
如果您需要/希望能够查找模板,您可以使用以下内容(创建一个隔离的容器):
Ember.testing = true;
MyAwesomeComponent = Ember.Component.extend();
function isolatedContainer() {
var container = new Ember.Container();
container.optionsForType('component', { singleton: false });
container.optionsForType('view', { singleton: false });
container.optionsForType('template', { instantiate: false });
container.optionsForType('helper', { instantiate: false });
return container;
}
function createComponent(componentName, factory, options) {
var fullName = 'component:' + componentName,
templateFullName = 'template:components/' + componentName;
container.register(fullName, factory);
if (container.has(templateFullName)) {
container.injection(fullName, 'layout', templateFullName);
}
var Component = container.lookupFactory(fullName),
component = Component.create(options);
Ember.run(function(){
component.appendTo('#qunit-fixture');
});
return component;
}
function registerTemplate(name, template){
if (typeof template !== 'function') {
template = Ember.Handlebars.compile(template);
}
container.register('template:' + name, template);
}
var container;
module('component testing sample', {
setup: function(){
container = isolatedContainer();
},
teardown: function(){
Ember.run(container, 'destroy');
}
});
test('a component with template', function(){
registerTemplate('components/my-awesome', 'woot woot{{fullName}}');
var component = createComponent('my-awesome', MyAwesomeComponent);
equal(component.$().text(), 'woot woot');
});
test('a component with custom options and a template', function(){
registerTemplate('components/my-awesome', '{{fullName}}');
var component = createComponent('my-awesome', MyAwesomeComponent, {fullName: 'Robert Jackson'});
equal(component.$().text(), 'Robert Jackson');
});
JSBin容器版本。