In Ember, in order to test the logic in our Glimmer components, we write integration tests. We can test the value returned from a getter by writing an assertion against the DOM to verify it was rendered correctly. We can also simulate user events and write assertions against the DOM.
Recently I found myself in a situation where I couldn't test some new component logic via an integration test because of constraints that were out of my control. I considered refactoring the code and moving it to make it easier to test, but ultimately I wanted to minimize the amount of changed code while having some test coverage, so I resorted to a component unit test. This isn't something I would generally recommend, but if you find yourself in a similar sitation, here is an example.
For our example, let's say we have a Foo
component that we'd invoke as such:
<Foo @a= @b= />
To generate a unit test, not an integration test, for our Glimmer component, we can run the following:
ember g component-test foo --unit
At the time of this writing, Ember CLI (5.9.0) will generate a component unit test that fails:
import { module, test } from 'qunit';
import { setupTest } from 'component-unit-tests/tests/helpers';
module('Unit | Component | foo', function (hooks) {
setupTest(hooks);
test('it exists', function (assert) {
let component = this.owner.factoryFor('component:foo').create();
assert.ok(component);
});
});
Let's update our component to have some getter:
import Component from '@glimmer/component';
export default class FooComponent extends Component {
get bar() {
const { a, b } = this.args;
return a + b;
}
}
We can test that getter directly with the following:
import { module, test } from "qunit";
import { setupTest } from "ember-qunit";
module("Unit | Component | foo", function (hooks) {
setupTest(hooks);
test("the bar getter", function (assert) {
const { class: FooComponentClass } = this.owner.factoryFor("component:foo");
const componentManager = this.owner.lookup("component-manager:glimmer");
const fooComponent = componentManager.createComponent(FooComponentClass, {
named: {
a: 1,
b: 2,
},
});
assert.strictEqual(fooComponent.bar, 3);
});
});