Ember testing utilities.
- Installation
- [Getting Started](#Getting Started)
- Contributing
ember install ember-test-utils
ember-test-utils provides a set of utilities to help you in testing Ember modules. This library requires you
use ember-mocha
as your testing framework. It provides shortcuts for working with:
Provided test helpers:
mockComponent
- creates a mock component to easily test the component dependency injection patternstubService
- allows you to stub a service
Two shortcuts (integration
, and unit
) are provided to help transform
import {render} from '@ember/test-helpers'
import {expect} from 'chai'
import {setupRenderingTest} from 'ember-mocha'
import hbs from 'htmlbars-inline-precompile'
import {describe, it} from 'mocha'
describe('Integration / MyGreetingComponent', function () {
setupRenderingTest()
it('renders', async function () {
this.set('name', 'John')
await render(hbs`{{my-greeting name=name}}`)
expect(this.element).to.not.equal(undefined)
})
})
into
import {render} from '@ember/test-helpers'
import {expect} from 'chai'
import hbs from 'htmlbars-inline-precompile'
import {describe, it} from 'mocha'
import {integration} from 'ember-test-utils/test-support/setup-component-test'
const test = integration('my-greeting')
describe(test.label, function () {
test.setup()
it('should render', async function () {
this.set('name', 'John')
await render(hbs`{{my-greeting name=name}}`)
expect(this.element).to.not.equal(undefined)
})
})
and
import {expect} from 'chai'
import {setupTest} from 'ember-mocha'
import {describe, it} from 'mocha'
describe('Unit / MyGreetingComponent', function () {
setupTest()
it('should exist', async function () {
// creates the component instance
let component = this.owner.__container__.factoryFor('component:my-greeting').create()
expect(component).not.to.equal(undefined)
})
})
into
import {expect} from 'chai'
import {describe, it} from 'mocha'
import {unit} from 'ember-test-utils/test-support/setup-component-test'
const test = unit('my-greeting', ['component:foo', 'helper:bar'])
context = test.setup()
it('should exist', function () {
// creates the component instance
let component = context.subject.call(this)
expect(component).not.to.equal(undefined)
})
})
The following shortcuts are provided:
The adapter
helper allows you to turn this:
import {expect} from 'chai'
import {setupTest} from 'ember-mocha'
import {describe, it} from 'mocha'
describe('DemoAdapter', function () {
setupTest()
// Replace this with your real tests.
it('exists', function () {
const adapter = this.owner.lookup(`adapter:demo`)
expect(adapter).not.to.equal(undefined)
})
})
into
import {expect} from 'chai'
import {describe, it} from 'mocha'
import {adapter} from 'ember-test-utils/test-support/setup-test'
const test = adapter('demo', ['adapter:foo'])
describe(test.label, function () {
test.setup()
// Replace this with your real tests.
it('exists', function () {
let adapter = this.subject()
expect(adapter).not.to.equal(undefined)
})
})
The controller
helper allows you to turn this:
import {expect} from 'chai'
import {setupTest} from 'ember-mocha'
import {describe, it} from 'mocha'
describe('DemoController', function () {
setupTest()
// Replace this with your real tests.
it('exists', function () {
let controller = this.owner.lookup('controller:demo')
expect(controller).not.to.equal(undefined)
})
})
into
import {expect} from 'chai'
import {describe, it} from 'mocha'
import {controller} from 'ember-test-utils/test-support/setup-test'
const test = controller('demo')
describe(test.label, function () {
test.setup()
// Replace this with your real tests.
it('exists', function () {
let controller = this.subject()
expect(controller).not.to.equal(undefined)
})
})
The helper
helper allows you to turn this:
import {expect} from 'chai'
import {setupTest} from 'ember-mocha'
import {describe, it} from 'mocha'
describe('DemoHelper', function () {
setupTest()
// Replace this with your real tests.
it('exists', function () {
let helper = this.owner.lookup('helper:demo')
expect(helper).not.to.equal(undefined)
})
})
into
import {expect} from 'chai'
import {describe, it} from 'mocha'
import {helper} from 'ember-test-utils/test-support/setup-test'
const test = helper('demo')
describe(test.label, function () {
test.setup()
// Replace this with your real tests.
it('exists', function () {
let helper = this.subject()
expect(helper).not.to.equal(undefined)
})
})
The model
helper allows you to turn this:
import {expect} from 'chai'
import {setupTest} from 'ember-mocha'
import {describe, it} from 'mocha'
describe('Unit: PersonModel', function () {
setupTest()
it('exists', function () {
let model = this.owner.lookup('model:person')
expect(model).not.to.equal(undefined)
})
})
into
import {expect} from 'chai'
import {describe, it} from 'mocha'
import {model} from 'ember-test-utils/test-support/setup-test'
const test = model('person')
describe(test.label, function () {
test.setup()
it('exists', function () {
let model = this.subject()
expect(model).not.to.equal(undefined)
})
})
The module
helper is a catch-all to let you unit test any module, it allows you to turn this:
import {expect} from 'chai'
import {setupTest} from 'ember-mocha'
import {describe, it} from 'mocha'
describe('DemoController', function () {
setupTest()
// Replace this with your real tests.
it('exists', function () {
let controller = this.subject('controller:demo')
expect(controller).not.to.equal(undefined)
})
})
into
import {expect} from 'chai'
import {describe, it} from 'mocha'
import {module} from 'ember-test-utils/test-support/setup-test'
const test = module('controller:demo')
describe(test.label, function () {
test.setup()
// Replace this with your real tests.
it('exists', function () {
let controller = this.subject()
expect(controller).not.to.equal(undefined)
})
})
The route
helper allows you to turn this:
import {expect} from 'chai'
import {setupTest} from 'ember-mocha'
import {describe, it} from 'mocha'
describe('DemoController', function () {
setupTest()
// Replace this with your real tests.
it('exists', function () {
let route = this.owner.lookup('route:demo')
expect(route).not.to.equal(undefined)
})
})
into
import {expect} from 'chai'
import {describe, it} from 'mocha'
import {route} from 'ember-test-utils/test-support/setup-test'
const test = route('demo')
describe(test.label, function () {
test.setup()
// Replace this with your real tests.
it('exists', function () {
let route = this.subject()
expect(route).not.to.equal(undefined)
})
})
The only difference between model
and serializer
is what the description of the test will end up being:
Unit / Model / model-name
vs.
Unit / Serializer / model-name
The service
helper allows you to turn this:
import {expect} from 'chai'
import {setupTest} from 'ember-mocha'
import {describe, it} from 'mocha'
describe('DemoService', function () {
setupTest()
// Replace this with your real tests.
it('exists', function () {
let service = this.owner.lookup('service:demo')
expect(service).not.to.equal(undefined)
})
})
into
import {expect} from 'chai'
import {describe, it} from 'mocha'
import {service} from 'ember-test-utils/test-support/setup-test'
const test = service('demo')
describe(test.label, function () {
test.setup()
// Replace this with your real tests.
it('exists', function () {
let service = this.subject()
expect(service).not.to.equal(undefined)
})
})
A helper to allow easy testing of the component dependency injection pattern. This helper will create a mock component
with the default name mock-component
. The name can be set by passing a String <name>
as the second parameter.
The third parameter allows you to pass any properties into the component as an Object {classNames: 'my-classname'}
.
Credit goes to poteto for the initial implementation of this idea.
import {render} from '@ember/test-helpers'
import {expect} from 'chai'
import {registerMockComponent, unregisterMockComponent} from 'ember-test-utils/test-support/mock-component'
import {integration} from 'ember-test-utils/test-support/setup-component-test'
import hbs from 'htmlbars-inline-precompile'
import {afterEach, beforeEach, describe, it} from 'mocha'
const test = integration('demo-component')
describe(test.label, function () {
test.setup()
beforeEach(async function () {
registerMockComponent(this)
await render(hbs`
{{demo-component
injectComponent=(component 'mock-component')
}}
`)
})
afterEach(function () {
unregisterMockComponent(this)
})
it('should render the injectComponent with default name', function () {
expect(this.element).to.not.equal(undefined)
})
})
or with a user provided name
and options: {}
import {render} from '@ember/test-helpers'
import {expect} from 'chai'
import {registerMockComponent, unregisterMockComponent} from 'ember-test-utils/test-support/mock-component'
import {integration} from 'ember-test-utils/test-support/setup-component-test'
import hbs from 'htmlbars-inline-precompile'
import {afterEach, beforeEach, describe, it} from 'mocha'
const test = integration('demo-component')
describe(test.label, function () {
test.setup()
beforeEach(async function () {
registerMockComponent(this, 'mock-inject', {
classNames: 'mock-inject',
title: 'My Title',
layout: hbs`
<h1>{{title}}</h1>
`
})
await render(hbs`
{{demo-component
injectComponent=(component 'mock-inject')
}}
`)
})
afterEach(function () {
unregisterMockComponent(this, 'mock-inject')
})
it('should render the injectComponent with provided layout', function () {
expect(this.element.querySelector('.mock-inject').textContent).to.equal('My Title')
})
})
This helper will allow the easy creation of stubs for services. If a user wishes to stub the store
the following methods are setup by default
import {expect} from 'chai'
import Ember from 'ember'
import {route} from 'ember-test-utils/test-support/setup-test'
import {stubService} from 'ember-test-utils/test-support/stub'
import {afterEach, beforeEach, describe, it} from 'mocha'
import sinon from 'sinon'
const test = route('demo', ['model:demo-user'])
describe(test.label, function () {
test.setup()
let route, sandbox, store, params
beforeEach(function () {
sandbox = sinon.sandbox.create()
store = stubService(this, sandbox, 'store')
route = this.subject()
})
afterEach(function () {
sandbox.restore()
sandbox = null
route = null
store = null
params = null
})
describe('model()', function () {
describe('when you set some properties', function () {
beforeEach(function () {
params = {
filter: '[name]=',
'page[limit]': 20,
'page[offset]': 0,
sort: '-last-modified-time'
}
route.model(params)
})
it('should query for user record with username', function () {
expect(store.queryRecord).to.have.been.calledWith('demo-user', {username: '[email protected]'})
})
})
})
})
Out of box having ember-test-utils
in your project will make your vendor.js asset slightly larger, as of 2017-02-15
this increase in size is approximately 0.08 KB. If you want to keep this out of your build for certain environments
you can add the following configuration to your package.json
:
{
"ember-test-utils": {
"excludeFromEnvironments": ["production"]
}
}
If you'd like to use the custom Mocha reporter provided by this addon then your testem.js
file should look something
like this:
var Reporter = require('ember-test-utils/reporter')
module.exports = {
disable_watching: true,
framework: 'mocha',
launch_in_ci: [
'Chrome'
],
launch_in_dev: [
'Chrome'
],
reporter: new Reporter(),
test_page: 'tests/index.html?hidepassed'
}
NOTE: This reporter will group test results into two sections: failed and passed. Each section is sorted from slowest test to fastest test so you can see which tests are causing your CI to come to a crawl.
If you want to lint your Dockerfile's, templates, Javascript, Markdown, and SASS files you can simply run:
./node_modules/.bin/lint-all-the-things
or even better add the following script to your package.json
:
{
"scripts": {
"lint": "lint-all-the-things"
}
}
and run
npm run lint-all-the-things
Many eslint errors and warnings can be automatically fixed using the --fix
command line argument. For example,
./node_modules/.bin/lint-all-the-things --fix
npm run lint-all-the-things -- --fix
If you want to lint your template files you can simply run:
./node_modules/.bin/lint-docker
or even better add the following script to your package.json
:
{
"scripts": {
"lint-docker": "lint-docker"
}
}
and run
npm run lint-docker
If you want to lint your Javascript files you can simply run:
./node_modules/.bin/lint-javascript
or even better add the following script to your package.json
:
{
"scripts": {
"lint-js": "lint-javascript"
}
}
and run
npm run lint-js
If you would like any Javascript files to be ignored during linting simply create a .eslintignore
file in the root
of your project and populate it with one
glob pattern per line.
If you want to lint your Markdown files you can simply run:
./node_modules/.bin/lint-markdown
or even better add the following script to your package.json
:
{
"scripts": {
"lint-md": "lint-markdown"
}
}
and run
npm run lint-md
If you would like any Markdown files to be ignored during linting simply create a .remarkignore
file in the root
of your project and populate it with one
glob pattern per line.
If you want to lint your SASS files you can simply run:
./node_modules/.bin/lint-sass
or even better add the following script to your package.json
:
{
"scripts": {
"lint-sass": "lint-sass"
}
}
and run
npm run lint-hbs
If you want to lint your template files you can simply run:
./node_modules/.bin/lint-htmlbars
or even better add the following script to your package.json
:
{
"scripts": {
"lint-hbs": "lint-htmlbars"
}
}
and run
npm run lint-hbs
By default the
recommended ember-template-lint
rules are enforced. If you would like to enable/disable other rules, you can do so by creating a
.template-lintrc.js
file in the root of your project per
these instructions.
This following outlines the details of collaborating on this Ember addon:
git clone
this repositorynpm install
bower install
npm test
(Runsember try:testall
to test your addon against multiple Ember versions)ember test
ember test --server
ember build
For more information on using ember-cli, visit http://www.ember-cli.com/.