Series: Automated Testing

Testing Part 2-The ember-cli-mirage database

Published on Oct 21, 2016

How do you quickly build up a server and the associated database?

In this episode we define the /monsters to return 10 fully defined monsters and /monsters/:id to return the correct monster.

To do that, we create our first ember-cli-mirage factory and scenario, then combine it with some routing tricks.


Links

Code

$ ember g mirage-model monster
$ ember g mirage-factory monter
//mirage/models/monster.js
import { Model } from 'ember-cli-mirage';

export default Model.extend({
});
//mirage/factories/monster.js
import { Factory } from 'ember-cli-mirage';

export default Factory.extend({
  name(i) {return 'Sparkachu' + i },
  level: 3,
  price: 15,
  image_url: "https://s3.amazonaws.com/monsterbattle/electric.png"
});
//mirage/scenarios/default.js
export default function(server) {
  server.createList('monster', 10)
})
//mirage/serializers/application.js
import { JSONAPISerializer, ActiveModelSerializer, RestSerializer } from 'ember-cli-mirage';
// in real app, only import the one you need

export default ActiveModelSerializer.extend({
});
//mirage/config.js
export default function() {
  this.namespace = '/v2'

  this.get('/monsters');
  this.get('/monsters/:id');
})

Transcript

In our last episode, we installed ember-cli-mirage and we created the first route on the mirage server. And in that route, we returned one single solitary monster, and since then we’ve added a bit more information to make it more complete. So what we get is something like this, pretty good, but what if we need to have more monsters? I mean we had quite a few on there when we were using the other server. If we want to just have one for every single monster listed out like this, that’d be pretty crazy. And then what about when we want to get an individual monster? So if we reload this page here, then we’ll get an error message because we haven’t defined the /v2/monsters/2 route. And using this formulation that we have here, we’d have to get(''/monsters/:id'', and then we’d have to have for each id that’s possible, we’d have to list it out again, and the same for editing, deleting, and all that. Just not a very good situation. So that’s where the ember-cli-mirage internal database comes in. Rather than explain in the abstract what that does, let’s go ahead and get started with it and then you’ll see it in action.

So we can go here to our command line and we can generate a mirage-model and we’ll do that for monsters. This will generate a model called monster. It’ll generate this file, and we don’t actually need to define anything else here. Then we’ll generate a mirage-factory for monster. So we’ll expand this factory and we’ll give it all the attributes that we want it to return, that we want this data to have. So we’ll start off with the name, and we could have it just like this. So each one of them generated from this Factory would be Sparkachu. We could also do it like this, and so it would be 'Sparkachu' and then + i, so the i in this case is just an incrementing number. So the first one would be Sparkachu1, next one Sparkachu2, and so on.

Alright. So now we get to our level. We’ll just go ahead and give them all a level of 3, and we’ll give them all a price of 15, and then the image_url, and we’re going to put this in underscore since that’s what we would be getting from the server, even though within our ember app they’ll be like that. Then for that we’ll paste in that image_url.

So we’ve got our actual ember data model, then we have our ember-cli-mirage Model where we don’t have much defined/to find, then we have our Factory which determines what data is going in to each of the generated models.

Now let’s go to our scenarios/default file in order to generate some monsters for our default scenario. So we’ll uncomment that and then call server.createList. So we’re going to create monsters and we’re going to create 10 of them. So that’ll use our factory and just pump out 10 Sparkachus.

Now that we’ve set all of that up, let’s go back to our config file and handle some of these routes. So here we’re going to pass in a schema and a request. Well, they’ve always been passed in but now we’re recognizing that. And then in the schema, we’re going to search for the monsters and get all of them. So we’re going to return those. And that means we can delete all this. So this will get us all 10 of our Sparkachus.

So we’ll check our page and there is nothing showing up, even though it looks like we’re getting 10 Sparkachus here just as we would expect. What’s happening? We’ll notice that this is a data array, so it’s an adapter problem. Our app is using the ActiveModelAdapter and therefore the ActiveModelSerializer, while mirage is using the JSONAPISerializer. The good news is that it also comes with the ActiveModelSerializer as well as the RestSerializer. So we’re going to use the ActiveModelSerializer. And now that they’re harmonized we can see that this is mostly working. There is one more problem. In our mirage factory we need to make sure to return the value. And there we go. We have our 10 factory-made Sparkachus.

Now because this is ember land and we like sane defaults, there is a sane default for the get. So if you have a slash and then a plural of something you have a model and a factory for, then the sane default is to return all of that from the schema. So we can do this and the result is exactly the same. There is also a sane default for what you would call a show route. So this is if we’re just grabbing one of them. And that means that when we go to a page like this and reload, there are no more errors.

And that is how we reduced something that was fairly large at the beginning and incomplete and repeating itself into these two short lines. And you may say hey, but we made these other files and did this stuff here, and that’s correct, but these are things that will continue to be used when we’re building up this server.

That’s it for this episode, but I hope you join us in the next one where we take the server that we’ve created here and we use it to create our first test.

Automated Testing

Subscribe to our mailing list