Mocking Integration Test Data with Ember CLI Mirage
● 3 minute readYou already know how to test your components but… how do you mock your complex data model?
In that guide we created a helper that returns a bunch of Ember.Object
s. This approach is perfect to get up and running but falls short in many aspects. For example if you need to test relationships.
Enter the fantastic Ember CLI Mirage.
Setting it all up
$ ember install ember-cli-mirage
You should notice a file structure created at app/mirage
! (Otherwise, try running ember generate ember-cli-mirage
.)
Following the Wine Bar application in the previous guide, our first “backend” model will be called Wine
and located at app/mirage/factories/wine.js
. We create the file and make it look like this:
// app/mirage/factories/wine.js
import Mirage, {faker} from 'ember-cli-mirage';
export default Mirage.Factory.extend({
name: faker.list.cycle('Zisola Sicilia',
'Ribera del Duero',
'Clos Fourtet St.-Emilion',
'Blandy Bual Madeira',
'Baer Ursa',
'Tenet Syrah Columbia Valley',
'Oddero Barolo',
'Lavau Gigondas',
'Duorum Douro',
'Philippe Alliet Chinon',
'Orin Swift Machete'),
quantity: faker.list.random(23, 54, 12, 10, 4, 280)
});
The package faker
ships with Mirage, we’ll use it to return names from a list and generate random quantities for our wine stock.
There are several options for our model attributes:
// app/mirage/factories/wine.js
import Mirage from 'ember-cli-mirage';
export default Mirage.Factory.extend({
name: ...,
quantity: ...,
age: 10,
recommended: true,
inStock() {
return this.quantity > 0;
},
cellar(i) {
return `Cellar ${i}`;
}
});
Mirage factories docs have further information.
Mocking the API
Naturally, we’ll need to setup endpoints for retrieving these fake models:
// app/mirage/config.js
export default function() {
this.get('/wines');
this.put('/wines/:id');
}
Ember CLI Mirage 0.1.x exposes a REST API and Ember Data should be aware. Let’s ensure we have the correct adapter and serializer:
# if needed
$ ember g adapter application
$ ember g serializer application
Double check:
- the adapter extends from
DS.RESTAdapter
- the serializer extends from
DS.RESTSerializer
Hooking up Mirage to our integration tests
First thing we’ll do is create a helper at tests/helpers/start-mirage.js
to initialize Mirage:
// tests/helpers/start-mirage.js
import mirageInitializer from '../../initializers/ember-cli-mirage';
export default function startMirage(container) {
mirageInitializer.initialize(container);
}
And invoke it in our test setup hook:
// tests/integration/components/wine-stock-test.js
// -- or wherever your integration test is located
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import startMirage from '../../helpers/start-mirage';
moduleForComponent('wine-stock', 'Integration | Component | wine stock', {
integration: true,
setup() {
startMirage(this.container);
}
});
Perfect! Now we are ready to use Mirage in our tests:
// any test
test('it renders', function(assert) {
assert.expect(5);
const model = server.createList('wine', 12);
this.set('model', model);
this.render(hbs`{{wine-stock wines=model}}`);
// assertions...
});
That should work!
In development mode, Mirage will display the response of the mock server in the console.
Above we called createList
which returns plain objects – not Ember.Object
s. If we want to access properties the Ember way in our tests, we can do:
const model = server.createList('wine', 12).map(wine => Ember.Object.create(wine));
Definitely take some time to read Mirage’s excellent documentation and test drive it! It’s a great mock server that will be worth your while.
It’s also a perfect companion for development work if your models are not so simple.
Enjoyed this article? Don't miss my next one!
Leave me your e-mail for content that will help you master Ember: