QUnit helpers for testing Ember.js applications
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Core functions for setting up different types of tests with proper Ember context and helpers. Each setup function configures a specific testing environment for different scenarios.
Sets a global resolver which will be used to look up objects from each test's container.
/**
* Sets a Resolver globally which will be used to look up objects from each test's container
* @param resolver - The resolver instance to use for dependency injection
*/
function setResolver(resolver: Resolver): void;Usage Example:
import { setResolver } from 'ember-qunit';
import resolver from './helpers/resolver';
setResolver(resolver);Sets up unit tests that interact with Ember's dependency injection system without rendering.
/**
* Sets up unit tests for any kind of "module/unit" of your application
* that can be looked up in a container
* @param hooks - QUnit hooks object for beforeEach/afterEach setup
* @param options - Optional configuration for the test setup
*/
function setupTest(hooks: NestedHooks, options?: SetupTestOptions): void;
interface SetupTestOptions {
/** The resolver to use when instantiating container-managed entities */
resolver?: Resolver;
/** Whether to wait for settled state after each test, defaults to true */
waitForSettled?: boolean;
}Test Context Provides:
this.owner - Access to Ember's Dependency Injection systemthis.set(), this.setProperties(), this.get(), this.getProperties() - Property managementthis.pauseTest() - Method to pause/resume tests for debuggingUsage Example:
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Service | User', function(hooks) {
setupTest(hooks);
test('creates user correctly', function(assert) {
let service = this.owner.lookup('service:user');
let user = service.createUser('Alice', 'alice@example.com');
assert.equal(user.name, 'Alice');
assert.equal(user.email, 'alice@example.com');
});
test('can inject dependencies', function(assert) {
this.owner.register('service:config', ConfigStub);
let service = this.owner.lookup('service:user');
assert.ok(service.config);
});
});Sets up component and template testing with DOM interaction capabilities.
/**
* Sets up tests that need to render snippets of templates, including components and helpers
* @param hooks - QUnit hooks object for beforeEach/afterEach setup
* @param options - Optional configuration for the test setup
*/
function setupRenderingTest(hooks: NestedHooks, options?: SetupTestOptions): void;Extends setupTest with:
render() helperclick(), fillIn(), find(), etc.)this.render() - Renders template snippetsthis.element - Access to the rendered DOM elementUsage Example:
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render, click, find, fillIn } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
module('Integration | Component | user-form', function(hooks) {
setupRenderingTest(hooks);
test('renders form fields', async function(assert) {
await render(hbs\`<UserForm @user={{this.user}} />\`);
assert.dom('[data-test-name-field]').exists();
assert.dom('[data-test-email-field]').exists();
assert.dom('[data-test-submit-button]').exists();
});
test('submits form data', async function(assert) {
let submitted = false;
this.set('onSubmit', () => submitted = true);
await render(hbs\`<UserForm @onSubmit={{this.onSubmit}} />\`);
await fillIn('[data-test-name-field]', 'Alice');
await fillIn('[data-test-email-field]', 'alice@example.com');
await click('[data-test-submit-button]');
assert.ok(submitted);
});
});Sets up full acceptance testing with routing capabilities and application boot.
/**
* Sets up tests that interact with the whole application, for acceptance tests
* @param hooks - QUnit hooks object for beforeEach/afterEach setup
* @param options - Optional configuration for the test setup
*/
function setupApplicationTest(hooks: NestedHooks, options?: SetupTestOptions): void;Extends setupTest with:
click(), fillIn(), etc.)visit(), currentURL(), currentRouteName(), etc.)Usage Example:
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { visit, currentURL, click, fillIn } from '@ember/test-helpers';
module('Acceptance | User Registration', function(hooks) {
setupApplicationTest(hooks);
test('can register new user', async function(assert) {
await visit('/register');
assert.equal(currentURL(), '/register');
await fillIn('[data-test-name]', 'Alice');
await fillIn('[data-test-email]', 'alice@example.com');
await fillIn('[data-test-password]', 'secretpassword');
await click('[data-test-submit]');
assert.equal(currentURL(), '/dashboard');
assert.dom('[data-test-welcome]').containsText('Welcome, Alice!');
});
test('validates required fields', async function(assert) {
await visit('/register');
await click('[data-test-submit]');
assert.dom('[data-test-error]').exists();
assert.equal(currentURL(), '/register');
});
});interface NestedHooks {
/** Runs before the first test */
before<TC extends TestContext>(
fn: (this: TC, assert: Assert) => void | Promise<void>
): void;
/** Runs before each test */
beforeEach<TC extends TestContext>(
fn: (this: TC, assert: Assert) => void | Promise<void>
): void;
/** Runs after each test */
afterEach<TC extends TestContext>(
fn: (this: TC, assert: Assert) => void | Promise<void>
): void;
/** Runs after the last test */
after<TC extends TestContext>(
fn: (this: TC, assert: Assert) => void | Promise<void>
): void;
}Install with Tessl CLI
npx tessl i tessl/npm-ember-qunit