Search code examples
unit-testingember.jsember-cliqunitember-qunit

Unit test computed property on an Ember controller


The code from my controllers/cart.js:

export default Ember.Controller.extend({
  cartTotal: Ember.computed('model.@each.subTotal', function() {
    return this.model.reduce(function(subTotal, product) {
      var total = subTotal + product.get('subTotal');
      return total;
    }, 0);
  })
)};

This computed property loops over all the elements in the model, adding all the values of the subTotal property, returning a cart total.

cart-test.js

import { moduleFor, test } from 'ember-qunit';
import Ember from 'ember';

moduleFor('controller:cart', {
  // Specify the other units that are required for this test.
  // needs: ['controller:foo']
});

test('it exists', function(assert) {
  var controller = this.subject();
  assert.ok(controller);
});

test('cartTotal function exists', function(assert) {
  var controller = this.subject();
  assert.equal(controller.get('cartTotal'), 30, 'The cart total function exists');
});

The test fails with TypeError: Cannot read property 'reduce' of null because it obviously doesn't have a model to loop over.

How can I mock the dependencies of the cartTotal computed property to make the test pass?

Thanks!


Solution

  • Something along these lines maybe?

    import { moduleFor, test } from 'ember-qunit';
    
    import Ember from 'ember';
    
    var products = [
      Ember.Object.create({ name: 'shoe', subTotal: 10 }), 
      Ember.Object.create({ name: 'shirt', subTotal: 20 })];
    
    var model = Ember.ArrayProxy.create({
      content: Ember.A(products)
    });
    
    moduleFor('controller:cart', {
      beforeEach() {
        this.controller = this.subject();
      }
    });
    
    test('cartTotal', function(assert) {
      this.controller.set('model', model);
      assert.equal(this.controller.get('cartTotal'), 30, 'The cart total function exists');
    });