Ember CLI Mirage - Create mock and use fixture data?


#1

Hi all,

I’ve been trying to setup an acceptance test using ember-cli-mirage, but I’ve hit a roadblock. I’ve got a model, called pqr with a relation (one to one) to a model called pqr-standard.

I’ve defined a set of fixtures for pqr-standard as they are mostly fixed. I want to create an acceptance test that visits pqr/:id and comes with a pre-selected standard (as the presence of a given standard influences some parts of my form)

My thinking was something like:

server.loadFixtures();
server.create('pqr', { standard: ''} ) <---- Here lies the problem

I would like to load one of the fixture values in the standard property. I’ve tried making this work on the route handler side, but no luck

this.get('/pqrs/1', function({ db }, request) {
let pqr = db.pqrs.insert({
  standard: db.pqrStandards[0]
});
return pqr;
});

I’ve tried making on the acceptance-test file, by making a new server.create('pqr-standard') (and using it when creating the pqr) and the value is added to mirage’s database, but in my form I don’t see the value for the standard I’ve created.

So my questions are: How can I use, server.create(‘model’) and pass it an attribute which is a fixture? Or am I doing something wrong here?

Thanks!


#2

@corrspt The fixture is used to seed Mirage’s database, but when using server.create and Mirage’s ORM you still want to always be dealing with models (so the ORM can work its magic).

Let’s say you have this fixture file for your pqr-standard models:

// fixtures/pqr-standards.js
export default [
  { id: 1, name: 'Foo' }
]

When you call

server.loadFixtures()

This is going to load in that data into Mirage’s database. Now that means you can do

let firstStandard = server.schema.pqrStandards.find(1);

to get the actual Mirage model, which you can pass to server.create to set up the association on your new pqr model:

server.create('pqr', { standard: firstStandard })

Basically, think of fixtures or factories (server.create) calls as two ways to do the same thing: get data into Mirage’s database. You can always see all your data by running server.db.dump().


#3

Hi Sam, thanks a lot for your reply :slight_smile: I learned a few things

I forgot to mention I’m using:

  • Mirage 0.4.9
  • Ember 3.2.2
  • Ember Data 3.1.1

By now, I’ve tried a gazillion combinations, but here’s what I have: If I do what you say, and I do a server.db.dump() in the middle of my test, I do see the fixtures for pqr-standard and I do see a single pqr with a standardId attribute with value of 1.

However, when I render my acceptance test nothing is rendered in the standard field (an ember-power-select component) If I trigger an open on that ember-power-select I can see the pqr-standards fixtures as the list of options)

The only way I managed to have the standard field have a value was the following: In my beforeEach I did:

      this.store = this.owner.lookup('service:store')

And then in my test:

    run(() => {
         let pqr = this.store.findRecord('pqr', 1).then((pqr) => {
         this.store.findRecord('pqr-standard', 1).then((standard) => {
           pqr.set('standard', standard);
           visit(`pqrs/${pqr.id}`);
         });
       });
    });

Which tells me that things exist in the store, but that association with pqr and pqr-standard is not made at the ember data store level.

I guess my issue with Mirage is fixed, so thanks a lot for that :slight_smile: any tips on how I could keep on debugging this?


#4

Next step would be to look at the Mirage requests your Ember app is making, to make sure that the data is coming over the wire in the format Ember Data expects (including the relationship keys).

Try putting

server.logging = true;

at the top of your test, running it, and looking at the network request logs in Console. I’m expecting you’ll find something where your Ember app is getting just the pqr-standard models without the relationships (possibly you’re not using include: 'standard' in your call to findRecord or findAll?)


#5

Hi Sam, thanks for sticking with me, really appreciate it :slight_smile:

That tip on include: 'standard' + the logging did really help. My real backend includes the standard automatically without any need for adding the include in the query (in the model hook for the route). Once I added that include: standard to the model hook it started working. Although I don’t really need in “development/production”

Guess what I want to ask is… is it possible to “tell” mirage that a given attribute should be included by default?

Thanks a ton, this thing was basically blocking from making any kind of acceptance test with existing data (which are the most interesting ones) as basically everything depends on a standard being selected.


#6

You can add an include property to your mirage serializer for that model: http://www.ember-cli-mirage.com/docs/v0.4.x/serializers/#include


#7

Hi dknuten, thanks for pitching in. That seems to be exactly what I needed. Thanks to you and Sam for helping me out on this, truly appreciate it. I really do need try and learn mirage more :slight_smile:

Cheers!


#8

Glad you figured it out! By the way this is exactly the sort of thing Mirage is made for surfacing. We believe it’s important for everyone to understand how data is flowing back and forth between the Ember app and the backend, so having a good understanding of that in your own app will help you down the road when talking with the backend/API team & building new features.


#9

Makes total sense Sam, and since I’m my own backend team, it’s really nice that I can understand that flow :sweat_smile: