I am trying to test a component in my Ember application unit tests, and until now all is good except that I am at a point where the assertions need its template to be rendered.
To do so normally one would call
var comp = App.SomeNamedComponent.create();
var comp.appendTo(App.rootElement);
But while this does create the base element of the component, it does not render its template. After a few research, I ended-up finding out that neither templateName
nor template
properties are set on the component. So I decided to set the templateName
myself, but then it complains that A Component must have a parent view in order to yield.
.
I then decided to create another custom view in the test with a template using that component, but then I can't access the instance of the component...
I need to access the instance to make the assertions, and I need to have it's template rendered as some properties are calculated depending on the css of some elements in the template.
Component Testing involves testing of each object or parts of the software separately. Unit Testing involves testing of individual programs or modules for program execution.
In order to integration test the Ember application, you need to run the app within your test framework. Set the root element of the application to an arbitrary element you know will exist. It is useful, as an aid to test-driven development, if the root element is visible while the tests run.
This is how I typically test a component when a container is not needed (specifically when the template and layout are provided to the component programmatically):
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');
});
See an example JSBin.
If you need/want to be able to lookup the template you can use something like the following (which creates an isolated container):
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 of the container version.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With