Skip to content

Testing ​

As commands are isolated and self-containing a business logic, we can write for this. There are integration tests, to test the commands itself and you can use instances of commands to test your UIs

Integration Tests ​

At first the TrackingCommand as a subject we want to test:

ts
import { service } from '@ember/service';
import { Command } from 'ember-command';
import type TrackingService from '<your-app>/services/tracking';

export default class TrackCommand extends Command {
  @service declare tracking: TrackingService;

  execute(event: string, data?: unknown): void {
    this.tracking.track(event, data);
  }
}

Let's test the tracking command using ember-sinon-qunit to stub the tracking service:

ts
import { setupTest } from 'ember-qunit';
import { module, test } from 'qunit';

import { arrangeCommand } from 'ember-command/test-support';
import { TestContext } from 'ember-test-helpers';

import sinon from 'sinon';

import TrackingCommand from '<somewhere-in-your-module>';

module('Integration | Command | TrackingCommand', function (hooks) {
  setupTest(hooks);

  test('it tracks', async function (this: TestContext, assert) {
    this.owner.register('service:tracking', TrackingService);
    const trackingService = this.owner.lookup('service:tracking');

    const stub = sinon.stub(trackingService, 'track');
    const cmd = arrangeCommand(new TrackingCommand());

    cmd.execute('hello');

    assert.ok(stub.calledOnceWith('hello'));
  });
});

The arrangeCommand is the testing equivalent to the @command decorator to attach the owner and wires up dependency injection.

Rendering Tests ​

When your components accept commands as arguments, here is how to test them:

gts
import { setupTest } from 'ember-qunit';
import { module, test } from 'qunit';

import { arrangeCommandInstance } from 'ember-command/test-support';
import { TestContext } from 'ember-test-helpers';

import sinon from 'sinon';

import TrackingCommand from '<somewhere-in-your-module>';
import YourComponnent from '<somewhere-in-your-module>';

module('Rendering | YourComponent', function (hooks) {
  setupTest(hooks);

  test('it triggers a @cmd', async function (this: TestContext, assert) {
    const cmd = arrangeCommandInstance(new TrackingCommand());
    const stub = sinon.stub(cmd, 'execute');

    await render(
      <template>
        <YourComponent @command={{cmd}}/>
      </template>
    );

    await click('button');

    assert.ok(stub.calledOnce);
  });
});