In the quest to update my Ember addon from Ember 2.8 to 2.16+, I had some odd unit tests for mixins that needed to render components, but also have access to the component instance. This no longer works because Ember.Component
complains about not having a renderer.
We were previously creating components like:
let Component = Ember.Component.extend(FooMixin, props);
return Component.create();
This now throws an error like Error: Cannot instantiate a component without a renderer. Please ensure that you are creating <(subclass of Ember.Component):ember201> with a proper container/registry.
Container
To get access to the container, we cannot use the vanilla qunit module
. We must use one of the moduleFor
given to us by ember-qunit. We must also use integration: true
.
Old
import { module, test } from 'qunit';
New
import { moduleForComponent, test } from 'ember-qunit';
Rendering
We then need a way to render the component, but also have access to the component instance for calling methods from our mixin. We’re going to use moduleForComponent
with the normal hbs
renderer, with some tweaks to make sure we can access the rendered component instance later.
We need to register a stub-comp
component, to give us a stubbed component instance, and we’ll want to override the init
method of the component to set the componentInstance
on the test context. This will allow us to call methods from the component instance later by doing something like this.componentInstance.myMethod()
.
Here is an example of the full test setup:
moduleForComponent('Unit | Mixin | foo mixin', {
integration: true,
beforeEach() {
const testContext = this;
this.register(
'component:stub-comp',
Ember.Component.extend(TransitionMixin, {
init() {
this._super(...arguments);
testContext.componentInstance = this;
}
})
);
}
});
test('it can call component methods', function (assert) {
this.render(hbs`{{stub-comp}}`);
let component = this.componentInstance;
component.myMethod();
// Here you would use sinon to assert this was called or check values etc.
});
Hopefully this helps someone struggling with how to refactor their old unit tests that were manually rendering components!