TL;DR

Ember Twiddle

By default, a component generated by ember-cli will have an integration test created for it as well. These are very useful for testing the functionality of you component. The problem with integration tests is that they do not provide the granular level of testing we would get from a unit test. I often find that I’d like to pass a number of different values at my computed Properties to ensure they are behaving as expected. This is where the component unit test comes in.

A component unit test can be generated by providing the --unit flag to the ember-cli generator.

ember g component-test *component-name* --unit

The generated test will look like this:

import { moduleForComponent, test } from 'ember-qunit';

moduleForComponent('example-component', 'Unit | Component | example component', {
  // Specify the other units that are required for this test
  // needs: ['component:foo', 'helper:bar'],
  unit: true
});

test('it renders', function(assert) {

  // Creates the component instance
  /*let component =*/ this.subject();
  // Renders the component to the page
  this.render();
  assert.equal(this.$().text().trim(), '');
});

The newly created test is strange. It’s a unit test, but is rendering the component? That’s a bit odd; The good part is, if we remove the line this.render() and the assertion assert.equal(this.$().text().trim(), ''); this becomes a proper unit test. Here’s a quick example.

// app/components/example-component.js
import Ember from 'ember';

export default Ember.Component.extend({
  init() {
    this._super(...arguments);  

    this.firstName = 'Will';
    this.lastName = 'Smith';
  },

  fullName: Ember.computed('firstName', 'lastName', function() {
    return `${this.get('firstName')} ${this.get('lastName')}`;
  })
});
// tests/unit/components/example-component-test.js
import { moduleForComponent, test } from 'ember-qunit';

moduleForComponent('example-component', 'Unit | Component | example component', {
  unit: true
});

test('Computed Property: fullName', function(assert) {
  assert.expect(3);

  let component = this.subject();
  assert.equal(component.get('fullName'), 'Will Smith', "fullName is constructed using the first and last name attributes.");
  
  component.set('firstName', 'Jack');
  assert.equal(component.get('fullName'), 'Jack Smith', "Property is re-cmputed when firstName is changed");

  component.set('lastName', 'Jones');
  assert.equal(component.get('fullName'), 'Jack Jones', "Property is re-cmputed when lastName is changed");
});