Once you’ve defined your server’s routes, you’ll probably want to seed your database with some starting data. In development you use fixtures, and in testing you use factories.
Think of your fixture files as database tables. If you want to add some data to your users
table, create the file /app/mirage/fixtures/users.js
:
// app/mirage/fixtures/users.js
export default [
{ id: 1, name: 'Link' },
{ id: 2, name: 'Zelda' },
{ id: 3, name: 'Epona' }
];
Fixture filenames are always plural, and export arrays of POJOs. Every time your app boots and a Mirage server is instantiated, this data will be added to its database and available in route handlers via db.users
.
Note that you’re responsible for managing the ids of your fixtures. If you want relationships, you’ll need to manage the foreign keys yourself. You can use whatever convention you like, since you have full access to the db in your route handlers, but let’s look at a popular convention.
Suppose a user
has many addresses
. Your fixture data may look like this:
// app/mirage/fixtures/users.js
export default [
{ id: 1, name: 'Link' },
{ id: 2, name: 'Zelda' }
];
// app/mirage/fixtures/addresses.js
export default [
{ id: 1, name: '123 Hyrule Way', user_id: 1 },
{ id: 2, name: '11 Kokiri Forest St.', user_id: 1 },
{ id: 3, name: '5 Lost Woods Dr.', user_id: 2 }
];
Now you can use the shorthand this.get('/api/users/:id', ['user', 'addresses']
to return the user along with its related addresses.
In testing, you use factories; Mirage ignores your fixture files. This is so you can define your database state directly within your tests, making your tests more isolated and clarifying their intent.
If you’ve never used factories before, think of them as a simple way to create database records. You define factories by creating files under /mirage/factories/factory-name.js
. The name of the factory, which you reference in your tests, is determined by the filename.
Factories have attributes which can be strings, numbers or booleans, or functions:
// mirage/factories/user.js
import Mirage from 'ember-cli-mirage';
export default Mirage.Factory.extend({
name(i) { return `User ${i}`; },
age: 20,
admin: false
});
Functions take one parameter, the sequence number of the object being created. This lets you create records with dynamic attributes.
Each time this factory is used to create an object, it will have an autogenerated id
assigned to it, since it will be inserted into the database. So, the objects created from this factory will look like
{ id: 0, name: "User 0", age: 20, admin: false }
{ id: 1, name: "User 1", age: 20, admin: false }
{ id: 2, name: "User 2", age: 20, admin: false }
and so on.
To actually use your factories, use the server.create
and server.createList
methods in your acceptance tests.
test("I can view the users", function() {
server.createList('user', 3);
visit('/contacts');
andThen(function() {
equal( find('p').length, 3 );
});
});
Learn more about acceptance testing in the next section.