I'm trying to write a unit test to test my controller. I have a computed property that uses a computed property on the model.
I'm unsure of how to setup the test to load the data into the model.
Here I have my model:
App.User = DS.Model.extend({
name: DS.attr('string'),
roles: DS.hasMany('role'),
isInstructor: function(){
return this.hasRole('instructor');
}.property('roles'),
hasRole: function(role_name){
var roles = this.get('roles');
if(!Ember.isEmpty(roles)){
return roles.any(function(role){
return role.get('name') === role_name;
});
}
return false;
}
});
And here I have my controller:
App.MyClassDetailsController = Ember.ObjectController.extend({
students: function () {
return this.get('users').filter(function (user) {
return !user.get('isInstructor');
});
}.property('content.users.@each')
});
And in my test when I setup the content for the controller I do this:
myClassDetailsController.set('model', Ember.ObjectProxy.create({
id: 389,
name: 'bfcoding 101',
users: Ember.ArrayProxy.create({
content: [
Ember.ObjectProxy.create({id: 1, name: 'Joe', roles: Ember.ArrayProxy.create({content: [Ember.ObjectProxy.create({name: 'instructor'})]})}),
Ember.ObjectProxy.create({id: 2, name: 'vs', roles: Ember.ArrayProxy.create({content: [Ember.ObjectProxy.create({name: 'student'})]})}),
Ember.ObjectProxy.create({id: 3, name: 'Volcano', roles: Ember.ArrayProxy.create({content: [Ember.ObjectProxy.create({name: 'student'})]})})
]
})
}));
And that obviously doesn't load it correctly. Because when I call that students method:
myClassDetailsController.get('students.length')
It returns all of the users.
Here is a jsbin http://jsbin.com/zafod/1/
In the jsbin, when it filters over all the users, the isInstructor computed property never gets called because the model data was never loaded (I presume). When I make that call it comes back undefined.
So how do I load that data into the model?
Thanks!
isInstructor
lives on instances of App.User
, not on Ember.ObjectProxy
instances. You'd either need to create instances of App.User
or just defined isInstructor
on the proxy instance.
Personally I'd do the latter. In a perfect unit test world you are testing the controller, not App.User
so everything else should be mocked or presumed working perfect. Obviously as you switch to integration testing this all changes, but again, this is Unit Testing.
Ember.ObjectProxy.create({id: 1, isInstructor: true, name: 'Joe', roles: Ember.ArrayProxy.create({content: [Ember.ObjectProxy.create({name: 'instructor'})]})}),