I have a computed property that asks server for user data and then the other one that computes number of users. To propagate changes into the template, I'm using DS.PromiseArray wrapper. With this wrapper, I can't find an easy way to test this property.
// model
users: computed('name', function () {
let name = get(this, 'name');
return DS.PromiseArray.create({
promise: this.store.query('user', { name })
});
}),
numberOfUsers: computed('users', function () {
return get(this, 'users.length') || 0;
}),
// ....
test('numberOfUsers returns correct number', function (assert) {
let model = this.subject({
store: EmberObject.create({
query() {
return Promise.resolve([
{ name: 'Thomas' },
{ name: 'Thomas' },
{ name: 'Thomas' },
]);
}
}),
name: 'Thomas',
});
assert.equal(model.get('numberOfUsers'), 3);
});
This test fails with 0 !== 3. Any ideas?
Since model.get('users')
is a promise, model.get('numberOfUsers')
will not be 3 until the Promise resolves. In your test, you're immediately calling model.get('numberOfUsers')
, and that is using the initial value of model.get('users')
, which is an unresolved promise.
To get it to work, you could call users
and put your assert
inside the then
of that returned promise:
model.get('users').then((user) => {
assert.equal(model.get('numberOfUsers'), 3);
})
A couple of side notes:
It is conventional in Ember to do your data fetching in the Route's model hook, not in a component like this.
Also, there's no need to manually create a PromiseArray
in your application code, because an Ember Data query
returns a type of Promise Array already. So you can just return this.store.query('user', { name });
(If you do this, you'll have to change your test query stub to generate a PromiseArray
).