SlideShare a Scribd company logo
Rapid prototyping and
easy testing with Ember
CLI Mirage
1
Me
• Name: Krzysztof Białek
• Github:
github.com/krzysztofbialek
• Twitter: drwrum
• Company: Rebased
SPA and dynamic server
data
• No backend api present yet
• Backend api not yet stable
• Mocking api in acceptance testing
Dealing with it - testing
with sinon
let project = JSON.stringify({
project: {
id: 1000,
links: {
devices: '/web_api/projects/1000/devices'
}
}
});
server.respondWith('GET', '/web_api/projects/1000', [200,
{"Content-Type":"application/json"}, project]);
Dealing with it - testing
with sinon
/* global server */
import Ember from 'ember';
export default Ember.Test.registerHelper('respondGET', function(app,
url, payload) {
let data = JSON.stringify(payload);
server.respondWith('GET', url, [200, {"Content-
Type":"application/json"}, data]);
});
respondGET('/web_api/projects/1000/devices', {
devices: [
{id: 1, name: "ipad"}
]
});
Dealing with it - Mocking with
ember cli http mocks
//server/mocks/author.js
module.exports = function(app) {
var express = require('express');
var authorRouter = express.Router();
var AUTHORS = [
{
id: 1,
name: 'Bad Motha Goose'
},
{
id: 2,
name: 'Concrete Octopus'
}
];
authorRouter.get('/', function(req, res) {
var ids = req.query.ids;
var authors;
if (ids) {
authors = authors.filter(function(b) {
return ids.indexOf(b.id.toString()) > -1;
});
}
else {
authors = authors;
}
res.send({"authors": authors});
});
app.use('/authors', authorRouter);
};
Dealing with it - the right
way
What can Ember CLI
Mirage do for you?
• Mocking of api in development
• Mocking endpoints in testing
• With it’s own ORM it can mimic ember-data
behaviour
• Bundled into application
• wraps around pretender.js
Define simple route
// mirage/config.js
export default function() {
this.namespace = 'api';
this.get('/authors', () => {
return {
authors: [
{id: 1, name: 'Zelda'},
{id: 2, name: 'Link'},
{id: 3, name: 'Epona'},
]
};
});
};
Define simple route
this.get('/events', () => {
let events = [];
for (let i = 1; i < 1000; i++) {
events.push({id: i, value: Math.random()});
};
return events;
});
this.get('/users/current', () => {
return {
name: 'Zelda',
email: 'z@hyrule.org'
};
});
Why so verbose?
// mirage/config.js
export default function() {
this.get('/authors', () => {
return {
authors: [
{id: 1, name: 'Zelda'},
{id: 2, name: 'Link'},
{id: 3, name: 'Epona'},
]
};
});
};
// mirage/config.js
export default function() {
this.get('/authors', (schema) => {
return schema.authors.all;
});
};
Data layer
• In memory database
• Models
• Factories
• Serializers
Going flexible with
models
// mirage/models/author.js
import { Model } from 'ember-cli-mirage';
export default Model;
// and use it in the route
// mirage/config.js
export default function() {
this.get('/authors', (schema) => {
return schema.authros.all;
});
}
Going flexible with
models
// app/routes/some-route
Ember.createObject('author', { name: 'Link', age: 123 })
// payload send with the request to ‘authors’ route
author: {
name: 'Link',
age: 123
}
// mirage/config.js
this.post('/authors', (schema, request) => {
let attrs = JSON.parse(request.requestBody).author;
return schema.authors.create(attrs);
});
Model associations
// mirage/models/author.js
import { Model, hasMany } from 'ember-cli-mirage';
export default Model.extend({
posts: hasMany()
});
// mirage/config.js
this.del('/authors/:id', (schema, request) => {
let author = schema.authors.find(request.params.id);
author.posts.delete();
author.delete();
});
Dynamic routes and
query params
this.get('/authors/:id', (schema, request) => {
let id = request.params.id;
return schema.authors.find(id);
});
this.get('/authors', (schema, request) => {
let someQuery = request.queryParams[‘some_query’];
return schema.authors.where({name: someQuery});
});
What if API is weird?
// mirage/serializers/application.js
import { Serializer } from 'ember-cli-mirage';
import Ember from 'ember';
const { dasherize } = Ember.String;
export default Serializer.extend({
keyForAttribute(key) {
return dasherize(key);
}
});
GET /authors/1
{
author: {
id: 1,
'first-name': 'Keyser',
'last-name': 'Soze',
age: 145
}
}
Taming API with
serialiser
Lets fake some data!
• Fixtures
• Factories
Fixtures - quick and rigid
// /mirage/fixtures/authors.js
export default [
{id: 1, firstName: 'Link'},
{id: 2, firstName: 'Zelda'}
];
// /mirage/fixtures/blog-posts.js
export default [
{id: 1, title: 'Lorem', authorId: 1},
{id: 2, title: 'Ipsum', authorId: 1},
{id: 3, title: 'Dolor', authorId: 2}
];
// mirage/scenarios/default.js
export default function(server) {
server.loadFixtures();
};
But…
Factories - also quick
but flexible
// mirage/factories/author.js
import { Factory } from 'ember-cli-mirage';
export default Factory.extend({
name(i) {
return `Author ${i}`;
},
age: 20,
admin: false
});
server.createList('author', 3);
{id: 1, name: "Author 1", age: 20, admin: false}
{id: 2, name: "Author 2", age: 20, admin: false}
{id: 3, name: "Author 3", age: 20, admin: false}
Factories - making data up
since… not so long ago
// mirage/factories/author.js
import { Factory, faker } from 'ember-cli-mirage';
export default Factory.extend({
firstName() {
return faker.name.firstName();
},
lastName() {
return faker.name.lastName();
},
age() {
// list method added by Mirage
return faker.list.random(18, 20, 28, 32, 45, 60)();
},
});
Factories - seeding data
in development
// mirage/scenarios/default.js
export default function(server) {
server.createList('blog-post', 10);
let author = server.create('author', {name: 'Zelda'});
server.createList('blog-post', 20, { author });
};
Factories - seeding data
in tests
test('I can view the photos', assert => {
server.createList('photo', 10);
visit('/');
andThen(function() {
assert.equal( find('img').length, 10 );
});
});
Acceptance testing -
overriding defaults
// mirage/factories/photo.js
import Mirage from 'ember-cli-mirage';
export default Mirage.Factory.extend({
title(i) {
// Photo 1, Photo 2 etc.
return `Photo ${i}`;
}
});
test("I can view the photos", assert => {
server.createList('photo', 10);
visit('/');
andThen(() => {
assert.equal( find('img').length, 10 );
});
});
Acceptance testing -
overriding defaults
test("I see the photo's title on a detail route", assert => {
let photo = server.create('photo', {title: 'Sunset over
Hyrule'});
visit('/' + photo.id);
andThen(() => {
assert.equal( find('h1:contains(Sunset over
Hyrule)').length, 1 );
});
});
Acceptance testing - make
sure server was called
test("I can change the lesson's title", assert => {
server.create('lesson', {title: 'My First Lesson'})
visit('/');
click('.Edit')
fillIn('input', 'Updated lesson');
click('.Save');
andThen(() => {
// Assert against our app's UI
assert.equal( find('h1:contains(Updated lesson)').length, 1
);
// Also check that the data was "persisted" to our backend
assert.equal( server.db.lessons[0].title, 'Updated
lesson');
});
});
Acceptance testing -
testing errors
test('the user sees an error if the save attempt fails',
function(assert) {
server.post('/questions', {errors: ['There was an error']},
500);
visit('/');
click('.new');
fillIn('input', 'New question');
click('.save');
andThen(() => {
assert.equals(find('p:contains(There was an
error)').length, 1);
});
});
That could be enough to
start…
Rapid prototyping and easy testing with ember cli mirage
Shorthands
// Expanded
this.get('/contacts', ({ contacts }) => {
return contacts.all(); // users in the second case
});
// Shorthand
this.get('/contacts'); // finds type by singularizing url
this.get('/contacts', 'users'); // optionally specify the collection as
second param
// Expanded
this.del('/contacts/:id', ({ contacts }, request) => {
let id = request.params.id;
let contact = contacts.find(id);
contact.addresses.destroy();
contact.destroy();
});
// Shorthand
this.del('/contacts/:id', ['contact', 'addresses']);
Easy peasy crud
// Resource
this.resource('contacts'); // available in 0.2.2+
// Equivalent shorthands
this.get('/contacts');
this.get('/contacts/:id');
this.post('/contacts');
this.put('/contacts/:id');
this.patch('/contacts/:id');
this.del('/contacts/:id');
Mix real api with fake
endpoints
this.passthrough('/addresses', '/contacts');
this.passthrough('/something');
this.passthrough('/else');
// just some verbs
this.passthrough('/addresses', ['post']);
this.passthrough('/contacts', '/photos', ['get']);
// other-origin
this.passthrough('http://api.foo.bar/**');
this.passthrough('http://api.twitter.com/v1/cards/**');
Happy faking!!!
• http://www.ember-cli-mirage.com
• https://github.com/pretenderjs/pretender

More Related Content

PDF
Vuejs testing
PDF
Testing Ember Apps: Managing Dependency
PDF
Containers & Dependency in Ember.js
PDF
Unit Testing Express and Koa Middleware in ES2015
PDF
Sane Async Patterns
PPTX
IndexedDB - Querying and Performance
PDF
Ember testing internals with ember cli
PDF
Promises are so passé - Tim Perry - Codemotion Milan 2016
Vuejs testing
Testing Ember Apps: Managing Dependency
Containers & Dependency in Ember.js
Unit Testing Express and Koa Middleware in ES2015
Sane Async Patterns
IndexedDB - Querying and Performance
Ember testing internals with ember cli
Promises are so passé - Tim Perry - Codemotion Milan 2016

What's hot (20)

PPTX
Full Stack Unit Testing
PPTX
How to Build SPA with Vue Router 2.0
PPTX
Test like a pro with Ember.js
PDF
Heroku pop-behind-the-sense
PDF
AngularJS - TechTalk 3/2/2014
PDF
Future of Web Apps: Google Gears
PDF
The JavaFX Ecosystem
PDF
20130528 solution linux_frousseau_nopain_webdev
PDF
An Introduction to Celery
PPTX
The road to Ember.js 2.0
PDF
Workshop 14: AngularJS Parte III
PDF
Building scalable applications with angular js
PDF
Django Celery - A distributed task queue
PPTX
Intro to Ember.JS 2016
PDF
Spring Boot Actuator
PPTX
Protractor framework architecture with example
PPT
Creating the interfaces of the future with the APIs of today
PDF
Workshop 26: React Native - The Native Side
PPTX
Ember - introduction
PDF
Ember.js - A JavaScript framework for creating ambitious web applications
Full Stack Unit Testing
How to Build SPA with Vue Router 2.0
Test like a pro with Ember.js
Heroku pop-behind-the-sense
AngularJS - TechTalk 3/2/2014
Future of Web Apps: Google Gears
The JavaFX Ecosystem
20130528 solution linux_frousseau_nopain_webdev
An Introduction to Celery
The road to Ember.js 2.0
Workshop 14: AngularJS Parte III
Building scalable applications with angular js
Django Celery - A distributed task queue
Intro to Ember.JS 2016
Spring Boot Actuator
Protractor framework architecture with example
Creating the interfaces of the future with the APIs of today
Workshop 26: React Native - The Native Side
Ember - introduction
Ember.js - A JavaScript framework for creating ambitious web applications
Ad

Viewers also liked (12)

PDF
Pieredze energoefektivitātes projekta īstenošanā
PDF
Siltumapgādes sistēmas renovācija/ rekonstrukcija daudzdzīvokļu mājā.
PPTX
Robotics Session day 1
PPTX
Redbull
PPTX
Māris Kļaviņš "Latvijas klimats un tā mainības raksturs"
PDF
Isha kriya-instructions-english
PPTX
Eddy current testing
PDF
PRESENTATION IN ENGLISH PDF - Trade Coin Club - Tcc Ingles
PDF
Assessing Your Agile Marketing Maturity Level
PPTX
Burglar alarm system
PDF
Hudson County, NJ Substance Abuse Stats
Pieredze energoefektivitātes projekta īstenošanā
Siltumapgādes sistēmas renovācija/ rekonstrukcija daudzdzīvokļu mājā.
Robotics Session day 1
Redbull
Māris Kļaviņš "Latvijas klimats un tā mainības raksturs"
Isha kriya-instructions-english
Eddy current testing
PRESENTATION IN ENGLISH PDF - Trade Coin Club - Tcc Ingles
Assessing Your Agile Marketing Maturity Level
Burglar alarm system
Hudson County, NJ Substance Abuse Stats
Ad

Similar to Rapid prototyping and easy testing with ember cli mirage (20)

PDF
Serverless Angular, Material, Firebase and Google Cloud applications
PDF
前端MVC 豆瓣说
PPTX
Django + Vue, JavaScript de 3ª generación para modernizar Django
PDF
20160905 - BrisJS - nightwatch testing
PDF
ForwardJS 2017 - Fullstack end-to-end Test Automation with node.js
PDF
Building and deploying React applications
PDF
Aurelia Meetup Paris
KEY
How and why i roll my own node.js framework
PDF
SproutCore and the Future of Web Apps
PDF
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
PPT
nodejs tutorial foor free download from academia
PDF
Introduction to VueJS & Vuex
PDF
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020
PPTX
Vue.js + Django - configuración para desarrollo con webpack y HMR
PDF
Node.js server-side rendering
PDF
A Story about AngularJS modularization development
PDF
using Mithril.js + postgREST to build and consume API's
PDF
Mirage For Beginners
PDF
Bonnes pratiques de développement avec Node js
PDF
JavaScript para Graficos y Visualizacion de Datos
Serverless Angular, Material, Firebase and Google Cloud applications
前端MVC 豆瓣说
Django + Vue, JavaScript de 3ª generación para modernizar Django
20160905 - BrisJS - nightwatch testing
ForwardJS 2017 - Fullstack end-to-end Test Automation with node.js
Building and deploying React applications
Aurelia Meetup Paris
How and why i roll my own node.js framework
SproutCore and the Future of Web Apps
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
nodejs tutorial foor free download from academia
Introduction to VueJS & Vuex
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020
Vue.js + Django - configuración para desarrollo con webpack y HMR
Node.js server-side rendering
A Story about AngularJS modularization development
using Mithril.js + postgREST to build and consume API's
Mirage For Beginners
Bonnes pratiques de développement avec Node js
JavaScript para Graficos y Visualizacion de Datos

Recently uploaded (20)

PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
A comparative analysis of optical character recognition models for extracting...
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
gpt5_lecture_notes_comprehensive_20250812015547.pdf
PPTX
Programs and apps: productivity, graphics, security and other tools
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
NewMind AI Weekly Chronicles - August'25-Week II
PPTX
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
DOCX
The AUB Centre for AI in Media Proposal.docx
PDF
MIND Revenue Release Quarter 2 2025 Press Release
PPTX
Machine Learning_overview_presentation.pptx
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Review of recent advances in non-invasive hemoglobin estimation
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PPTX
Cloud computing and distributed systems.
PPT
Teaching material agriculture food technology
PPTX
sap open course for s4hana steps from ECC to s4
PDF
Encapsulation_ Review paper, used for researhc scholars
Per capita expenditure prediction using model stacking based on satellite ima...
A comparative analysis of optical character recognition models for extracting...
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
gpt5_lecture_notes_comprehensive_20250812015547.pdf
Programs and apps: productivity, graphics, security and other tools
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
NewMind AI Weekly Chronicles - August'25-Week II
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
The AUB Centre for AI in Media Proposal.docx
MIND Revenue Release Quarter 2 2025 Press Release
Machine Learning_overview_presentation.pptx
Unlocking AI with Model Context Protocol (MCP)
Review of recent advances in non-invasive hemoglobin estimation
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Cloud computing and distributed systems.
Teaching material agriculture food technology
sap open course for s4hana steps from ECC to s4
Encapsulation_ Review paper, used for researhc scholars

Rapid prototyping and easy testing with ember cli mirage

  • 1. Rapid prototyping and easy testing with Ember CLI Mirage 1
  • 2. Me • Name: Krzysztof Białek • Github: github.com/krzysztofbialek • Twitter: drwrum • Company: Rebased
  • 3. SPA and dynamic server data • No backend api present yet • Backend api not yet stable • Mocking api in acceptance testing
  • 4. Dealing with it - testing with sinon let project = JSON.stringify({ project: { id: 1000, links: { devices: '/web_api/projects/1000/devices' } } }); server.respondWith('GET', '/web_api/projects/1000', [200, {"Content-Type":"application/json"}, project]);
  • 5. Dealing with it - testing with sinon /* global server */ import Ember from 'ember'; export default Ember.Test.registerHelper('respondGET', function(app, url, payload) { let data = JSON.stringify(payload); server.respondWith('GET', url, [200, {"Content- Type":"application/json"}, data]); }); respondGET('/web_api/projects/1000/devices', { devices: [ {id: 1, name: "ipad"} ] });
  • 6. Dealing with it - Mocking with ember cli http mocks //server/mocks/author.js module.exports = function(app) { var express = require('express'); var authorRouter = express.Router(); var AUTHORS = [ { id: 1, name: 'Bad Motha Goose' }, { id: 2, name: 'Concrete Octopus' } ]; authorRouter.get('/', function(req, res) { var ids = req.query.ids; var authors; if (ids) { authors = authors.filter(function(b) { return ids.indexOf(b.id.toString()) > -1; }); } else { authors = authors; } res.send({"authors": authors}); }); app.use('/authors', authorRouter); };
  • 7. Dealing with it - the right way
  • 8. What can Ember CLI Mirage do for you? • Mocking of api in development • Mocking endpoints in testing • With it’s own ORM it can mimic ember-data behaviour • Bundled into application • wraps around pretender.js
  • 9. Define simple route // mirage/config.js export default function() { this.namespace = 'api'; this.get('/authors', () => { return { authors: [ {id: 1, name: 'Zelda'}, {id: 2, name: 'Link'}, {id: 3, name: 'Epona'}, ] }; }); };
  • 10. Define simple route this.get('/events', () => { let events = []; for (let i = 1; i < 1000; i++) { events.push({id: i, value: Math.random()}); }; return events; }); this.get('/users/current', () => { return { name: 'Zelda', email: 'z@hyrule.org' }; });
  • 11. Why so verbose? // mirage/config.js export default function() { this.get('/authors', () => { return { authors: [ {id: 1, name: 'Zelda'}, {id: 2, name: 'Link'}, {id: 3, name: 'Epona'}, ] }; }); }; // mirage/config.js export default function() { this.get('/authors', (schema) => { return schema.authors.all; }); };
  • 12. Data layer • In memory database • Models • Factories • Serializers
  • 13. Going flexible with models // mirage/models/author.js import { Model } from 'ember-cli-mirage'; export default Model; // and use it in the route // mirage/config.js export default function() { this.get('/authors', (schema) => { return schema.authros.all; }); }
  • 14. Going flexible with models // app/routes/some-route Ember.createObject('author', { name: 'Link', age: 123 }) // payload send with the request to ‘authors’ route author: { name: 'Link', age: 123 } // mirage/config.js this.post('/authors', (schema, request) => { let attrs = JSON.parse(request.requestBody).author; return schema.authors.create(attrs); });
  • 15. Model associations // mirage/models/author.js import { Model, hasMany } from 'ember-cli-mirage'; export default Model.extend({ posts: hasMany() }); // mirage/config.js this.del('/authors/:id', (schema, request) => { let author = schema.authors.find(request.params.id); author.posts.delete(); author.delete(); });
  • 16. Dynamic routes and query params this.get('/authors/:id', (schema, request) => { let id = request.params.id; return schema.authors.find(id); }); this.get('/authors', (schema, request) => { let someQuery = request.queryParams[‘some_query’]; return schema.authors.where({name: someQuery}); });
  • 17. What if API is weird?
  • 18. // mirage/serializers/application.js import { Serializer } from 'ember-cli-mirage'; import Ember from 'ember'; const { dasherize } = Ember.String; export default Serializer.extend({ keyForAttribute(key) { return dasherize(key); } }); GET /authors/1 { author: { id: 1, 'first-name': 'Keyser', 'last-name': 'Soze', age: 145 } } Taming API with serialiser
  • 19. Lets fake some data! • Fixtures • Factories
  • 20. Fixtures - quick and rigid // /mirage/fixtures/authors.js export default [ {id: 1, firstName: 'Link'}, {id: 2, firstName: 'Zelda'} ]; // /mirage/fixtures/blog-posts.js export default [ {id: 1, title: 'Lorem', authorId: 1}, {id: 2, title: 'Ipsum', authorId: 1}, {id: 3, title: 'Dolor', authorId: 2} ]; // mirage/scenarios/default.js export default function(server) { server.loadFixtures(); };
  • 22. Factories - also quick but flexible // mirage/factories/author.js import { Factory } from 'ember-cli-mirage'; export default Factory.extend({ name(i) { return `Author ${i}`; }, age: 20, admin: false }); server.createList('author', 3); {id: 1, name: "Author 1", age: 20, admin: false} {id: 2, name: "Author 2", age: 20, admin: false} {id: 3, name: "Author 3", age: 20, admin: false}
  • 23. Factories - making data up since… not so long ago // mirage/factories/author.js import { Factory, faker } from 'ember-cli-mirage'; export default Factory.extend({ firstName() { return faker.name.firstName(); }, lastName() { return faker.name.lastName(); }, age() { // list method added by Mirage return faker.list.random(18, 20, 28, 32, 45, 60)(); }, });
  • 24. Factories - seeding data in development // mirage/scenarios/default.js export default function(server) { server.createList('blog-post', 10); let author = server.create('author', {name: 'Zelda'}); server.createList('blog-post', 20, { author }); };
  • 25. Factories - seeding data in tests test('I can view the photos', assert => { server.createList('photo', 10); visit('/'); andThen(function() { assert.equal( find('img').length, 10 ); }); });
  • 26. Acceptance testing - overriding defaults // mirage/factories/photo.js import Mirage from 'ember-cli-mirage'; export default Mirage.Factory.extend({ title(i) { // Photo 1, Photo 2 etc. return `Photo ${i}`; } }); test("I can view the photos", assert => { server.createList('photo', 10); visit('/'); andThen(() => { assert.equal( find('img').length, 10 ); }); });
  • 27. Acceptance testing - overriding defaults test("I see the photo's title on a detail route", assert => { let photo = server.create('photo', {title: 'Sunset over Hyrule'}); visit('/' + photo.id); andThen(() => { assert.equal( find('h1:contains(Sunset over Hyrule)').length, 1 ); }); });
  • 28. Acceptance testing - make sure server was called test("I can change the lesson's title", assert => { server.create('lesson', {title: 'My First Lesson'}) visit('/'); click('.Edit') fillIn('input', 'Updated lesson'); click('.Save'); andThen(() => { // Assert against our app's UI assert.equal( find('h1:contains(Updated lesson)').length, 1 ); // Also check that the data was "persisted" to our backend assert.equal( server.db.lessons[0].title, 'Updated lesson'); }); });
  • 29. Acceptance testing - testing errors test('the user sees an error if the save attempt fails', function(assert) { server.post('/questions', {errors: ['There was an error']}, 500); visit('/'); click('.new'); fillIn('input', 'New question'); click('.save'); andThen(() => { assert.equals(find('p:contains(There was an error)').length, 1); }); });
  • 30. That could be enough to start…
  • 32. Shorthands // Expanded this.get('/contacts', ({ contacts }) => { return contacts.all(); // users in the second case }); // Shorthand this.get('/contacts'); // finds type by singularizing url this.get('/contacts', 'users'); // optionally specify the collection as second param // Expanded this.del('/contacts/:id', ({ contacts }, request) => { let id = request.params.id; let contact = contacts.find(id); contact.addresses.destroy(); contact.destroy(); }); // Shorthand this.del('/contacts/:id', ['contact', 'addresses']);
  • 33. Easy peasy crud // Resource this.resource('contacts'); // available in 0.2.2+ // Equivalent shorthands this.get('/contacts'); this.get('/contacts/:id'); this.post('/contacts'); this.put('/contacts/:id'); this.patch('/contacts/:id'); this.del('/contacts/:id');
  • 34. Mix real api with fake endpoints this.passthrough('/addresses', '/contacts'); this.passthrough('/something'); this.passthrough('/else'); // just some verbs this.passthrough('/addresses', ['post']); this.passthrough('/contacts', '/photos', ['get']); // other-origin this.passthrough('http://api.foo.bar/**'); this.passthrough('http://api.twitter.com/v1/cards/**');
  • 35. Happy faking!!! • http://www.ember-cli-mirage.com • https://github.com/pretenderjs/pretender

Editor's Notes

  • #5: - using sinon pretender.js can be used as well define data and then server mock
  • #6: or you can use a wrapper to make it easier need to define it each time
  • #7: starts express js server needs node :( only mocking, no testing
  • #9: no need to have separate server can be used in production environment pretender can be configured with any options from it’s doc
  • #10: namespace like in adapters all calls to this url will be responded by mirage all routes in the config file namespace only for routes defined later handlers use common verbs
  • #11: namespace like in adapters all calls to this url will be responded by mirage all routes in the config file namespace only for routes defined later handlers use common verbs
  • #12: nicer for endpoints when we want to get all that is in database or some particular data as we will see in a bit
  • #14: sets database at runtime available generators schema is the instance of database to freely interact with
  • #15: model persisted in the database id assigned so ember-data can do it’s magic data is persisted in the single session to simulate real life exp same goes for other verbs, deleting models, retrieving collections searching
  • #16: finder method response codes
  • #18: like different key format that ember may expect with adapter app uses When you return a model or a collection from a route handler, Mirage serializes it into a JSON payload, and then responds to your Ember app with that payload. mirage ships with serialisers for jsonapi, rest and active model adapters it’s important to make the payload in same way like server will
  • #19: by default it takes all the attributes of the model and wraps it under model name key let’s assume server sends dasherized keys
  • #20: ok but we still need to get these responses payload from somewhere, right? couple of ways to do it
  • #21: think of them as database table loaded into mirage db return arrays of POJOS scenario js file to define what data should be loaded into db
  • #22: - it’s not the mirage way and it gets inconvenient very quickly
  • #23: - access to sequence which is only parameter available in factory
  • #24: faker there are more for example avatar or other images
  • #26: access to server create and create lists
  • #27: mirage is bundles with ember app in testing db is populated when app is booting reset after each test
  • #29: when testing UI we test to see changes but not always that means actually call to server was made. can be also tested by overriding route and testing against request sent by ember
  • #30: only valid route for the duration of test if it overrides something from config file it’s just for the test
  • #32: - mirage has a lot more to offer so I’ll highlight few other sweet features
  • #33: - we don’t want to write code we don’t need to
  • #34: - can be whitelisted or constrained to certain verbs