When testing an Ember Engine, we want to run acceptance tests with the dummy app, but unit and integration tests with the engine itself. We found a solution, and I wanted to share it for others and to see if there’s a better way.
We want most tests to use the engine’s resolve so that this.lookup('component:my-button')
finds the engine’s component (from the addon/ directory):
// tests/test-helper.js
import { start } from 'ember-qunit';
import { setResolver } from 'ember-test-helpers';
import engineResolverFor from 'ember-engines/test-support/engine-resolver-for';
setResolver(engineResolverFor('my-engine-name'));
start();
But for acceptance tests, we want to set up the dummy application so that we have a full application to run, like so:
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { visit, currentURL } from '@ember/test-helpers';
module('basic acceptance test', function(hooks) {
setupApplicationTest(hooks);
test('can visit /', async function(assert) {
await visit('/');
assert.equal(currentURL(), '/');
});
});
Because we never called setApplication
(as described in the ember-qunit readme), this will fail. But once we call setApplication
, it will override the setResolver
call and all unit and integration tests will fail. So we came up with a custom “setup” function that uses setupApplicationTest
under the hood:
// tests/helpers/dummy.js
import Application from '../../app';
import config from '../../config/environment';
import { setApplication } from '@ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit';
export function setupDummyApplicationTest({ beforeEach, afterEach }, options) {
const hooks = {
beforeEach(fn) {
return beforeEach(function(...args) {
setApplication(Application.create(config.APP));
return fn.apply(this, args);
});
},
afterEach(fn) {
return afterEach(function(...args) {
setApplication(null);
return fn.apply(this, args);
});
}
};
setupApplicationTest(hooks, options);
}
So we can fix the above example by swapping setupApplicationTest
with setupDummyApplicationTest
. And calling setApplication(null)
in afterEach()
allows the next test to use the engine’s resolver as specified in tests/test-helper.js.
Are there are any downsides to this approach? Or: is there a better pattern we should be using?