In this article I am going to show how to write model attribute and computed property test cases for ember applications.

I have been writing test cases from couple of days in GoodCity ember app. I will takeDesignation model as an example model to write test cases. Designation model has shown below.

models/designation.js

import Ember from 'ember';
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import { belongsTo, hasMany } from 'ember-data/relationships';

export default Model.extend({

  status:       attr('string'),
  createdAt:    attr('date'),
  recentlyUsedAt: attr('date'),
  code:         attr('string'),
  activity:     attr('string'),
  description:  attr('string'),
  detailType:   attr('string'),
  detailId:     attr('number'),

  contact:      belongsTo('contact', { async: false }),
  organisation: belongsTo('organisation', { async: false }),
  localOrder:   belongsTo('local_order', { async: false }),
  items:        hasMany('item', { async: true }),
  ordersPackages:    hasMany('ordersPackages', { async: false }),


  isLocalOrder: Ember.computed.equal('detailType', 'LocalOrder'),

  dispatchedItems: Ember.computed('items.@each.sentOn', function() {
    return this.get("items").rejectBy('sentOn', null);
  }),

  allItemsDispatched: Ember.computed('items.@each.isDispatched', function() {
    var items = this.get("items");
    return items.get('length') > 0 && items.filterBy('isDispatched', false).length === 0;
  }),

  designatedOrdersPackages: Ember.computed('ordersPackages.@each.state', function() {
    return this.get("ordersPackages").filterBy('state', "designated");
  }),

  dispatchedOrdersPackages: Ember.computed('ordersPackages.@each.state', function() {
    return this.get("ordersPackages").filterBy('state', "dispatched");
  }),

  designatedItems: Ember.computed('items.@each.sentOn', function() {
    return this.get("items").filterBy('sentOn', null);
  }),

  isInactive: Ember.computed('status', function(){
    return ["Sent", "Cancelled", "Closed"].indexOf(this.get("status")) >= 0;
  })

});

Lets start writing test case for status property of designation model:

test('check attributes', function(assert){

  var model = this.subject();
  var status = Object.keys(model.toJSON()).indexOf('status') > -1;

  assert.ok(status);

});

In this test case

Object.keys(model.toJSON()) will return array of model properties

["status", "createdAt", "recentlyUsedAt", "code", "activity", "description", "detailType", "detailId", "contact", "organisation", "localOrder"]

Than we are checking if model has status property by getting the index of staus and checking that index must be > -1 .
This way we can make sure some model propertie should be there otherwise test will fail.

Now we will write test case to check relationship with Item model, Designation model has relationship with item as shown below

items:        hasMany('item', { async: true })

To check this relationship

test('Relationships with other models', function(assert){
  assert.expect(2);
  var designation = this.store().modelFor('designation');
  var relationshipWithItem = Ember.get(designation, 'relationshipsByName').get('items');
  
  assert.equal(relationshipWithItem.key, 'items');
  assert.equal(relationshipWithItem.kind, 'hasMany');
});

Ember.get(designation, 'relationshipsByName').get('items'); will give the relationship between designation and item

enter image description here

Now we will write test case for dispatchedItems computed property.This function returns items with sentOn not null those are diptached items.

test('check dispatchedItems returns items with sentOn not null', function(assert){
  assert.expect(3);
  const model = this.subject();
  var store = this.store();
  var item1 = null;
  var item2 = null;
  var item3 = null;
  var despatchedItemsIds = null;

  Ember.run(function(){
    store.createRecord('item', { id: 1, sentOn: "12/07/2016" });
    store.createRecord('item', { id: 2, sentOn: "12/07/2016" });
    store.createRecord('item', { id: 3, sentOn: null });
    item1 = store.peekRecord('item', 1);
    item2 = store.peekRecord('item', 2);
    item3 = store.peekRecord('item', 3);
    model.get('items').pushObject(item1);
    model.get('items').pushObject(item2);
    model.get('items').pushObject(item3);
  });
  despatchedItemsIds = model.get('dispatchedItems').getEach('id');
  assert.equal(despatchedItemsIds.get('length'), 2);
  assert.equal(despatchedItemsIds[0], item1.get('id'));
  assert.equal(despatchedItemsIds[1], item2.get('id'));
});

We are creating 3 items, last item sentOn was null that means last item was not dispatched and item1 and item2 are dispatched items. Then we are calling dispatchedItems function on model and we are testing it should return only item1 and item2.

hope this helps.