How do I fake out the data that a component receives from the store?


#1

In my route’s model hook, I find all posts. In my template, I pass the model directly to my component which then takes the data, filters and sorts it to figure out a final result which is then displayed. The problem is that the component receives an instance of DS.AdapterPopulatedRecordArray which is the resolved value of this.store.findAll('post').

How do I fake out that DS.AdapterPopulatedRecordArray in my component test?


#2

Is the issue that you’re using properties and methods that are from DS.AdapterPopulatedRecordArray? In general, you would mock the shape of DS.AdapterPopulatedRecordArray, with is largely an Ember.ArrayProxy, in your test model.

But I don’t have enough context to fully understand the limitations you’re running up against.


#3

So I have something like this:

{{latest-ember-post posts=posts}}

where posts is a DS.AdapterPopulatedRecordArray after calling this.store.findAll('post') in the model hook. The component is supposed to display the most recent Ember blog post. The component has a computed property that filters all of the posts passed in to see if any of them have “Ember” in the title, sorts the list by the date in descending order, and returns the post at the top of the list. That filtering and sorting logic to find the most recent Ember post is what I want to unit test. To unit test it, I need to create something like a DS.AdapterPopulatedRecordArray and fill it with some fake data. That is where I get stuck. How would you go about testing this? On another note, that filtering/sorting logic, would you do that in a component computed property or move that to a service?


#4

Unless you’re calling methods off the prototype for DS.AdapterPopulatedRecordArray, you should be able to get away with creating just an Ember.ArrayProxy for your stubbed out posts object.

test('description', function(assert) {
  this.set('posts', Ember.ArrayProxy.create({
    content: [/*..*/]
  }));

  this.render(hbs`{{latest-ember posts=posts}}`);

  // assert ..
});

#5

Thanks! So this works, but I had to wrap each object in an Ember.Object.

Ember.ArrayProxy.create({
  content: [
    Ember.Object.create({ id: 1, title: 'asdf' }),
    Ember.Object.create({ id: 2, title: 'yuio' }),
  ]
});

This works, but feels wrong for some reason. Am I going about writing the component and/or testing it the wrong way?


#6

Somewhere in your component you’re relying on functions from Ember.Object – likely set and get. You can make it support pojos by using Ember.get/Ember.set in those places.

foo.get('bar'); -> Ember.get(foo, 'bar');
foo.set('bar', true); -> Ember.set(foo, 'bar', true);

Now foo can be POJO or an Ember Object.


#7

ah ok, sounds like another good approach. thanks for all the help!