Best practices for testing components that accept collection of models


#1

I have a component, that accepts a collection of models (ember-data). I also have http-mock setup for mock testing.

Now the question is when I’m testing this component, how should I pass it the collection of models that it needs?


#2

Assuming you have something like:

var component = this.subject();

(which you should, if you generated your test with ember-cli’s generators)

then the component is just a regular Ember object and you can set properties the usual way:

var articles = [{ id: 3, title: 'test', content: 'test'}];
component.set('articles', articles);

I wouldn’t recommend that you use http-mock or anything similar; that kind of solution is meant for integration / acceptance tests. Your component unit tests should not depend on whatever mock or real data your (fake) API is returning.


#3

But the way component interacts with model is using .get() and also looping through it using {{#each}} how can I mock up this functionality?


#4

I don’t think I understand what you’re trying to do. Can you show me what your component looks like?

In general, your component is completely isolated from its context, so setting properties on it is really the only thing you can / should do to set it up.


#5

@Fryie, the component is actually a component I built as an addon for ember, https://github.com/tolgaek/ember-table-it/

Basically with this addon, I have a component i can call with {{table-it columns=columnDefinitions rows=users}}

table-it component does a .get('content.meta') on the collection to get total_pages returned from server for pagination and passes it to row-it component which loops through it. So it’s not just a simple array since I have access to this models.get() method while still being able to loop through it.

table-it component is here https://github.com/tolgaek/ember-table-it/blob/master/addon/components/table-it.js table-it template is here https://github.com/tolgaek/ember-table-it/blob/master/app/templates/components/table-it.hbs


#6

when you do {{table-it columns=columnDefinitions rows=users}} what happens in the background is (loosely) something like:

var component = ...; //instantiate component
component.set('columns', columnDefinitions);
component.set('rows', users);

so you can do the same in your unit test.

If you want to be able to call get on your users object, you can do something like:

var users = Ember.Object.create({ content: { meta: ... } });

But I’m not exactly sure how you can set users up to be able to be iterated over. You’d have to dig into the API documentation for that.

IMO though, your component knows too much about the structure of the users array. It would probably be better to pass in the metadata separately:

{{table-it colums=columnDefinitions rows=users totalPages=users.meta.total_pages}}

edit: I guess Enumerable might do the trick.


#7

Oh I see what you mean. Thanks @Fryie. I think I thought about that before, and yes it does make more sense to split the totalPages, for the users as well