Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do we unit test a Model Mixin with ember-cli

I have few Ember.Mixin in my app that contains DS.attr() and / or DS.belongsTo(). I was wondering how should I unit test them ?

By default, ember-cli generate this test

test('it works', function(assert) {
  var MyModelObject = Ember.Object.extend(MyModelMixin);
  var subject = MyModelObject.create();
  assert.ok(subject);
});

But when I tried to interact with an DS.attr() I got the following error:

TypeError: Cannot read property '_attributes' of undefined
  at hasValue (http://localhost:4200/assets/vendor.js:90650:25)
  at Class.get (http://localhost:4200/assets/vendor.js:90730:13)
  at Descriptor.ComputedPropertyPrototype.get (http://localhost:4200/assets/vendor.js:29706:28)
  at Object.get (http://localhost:4200/assets/vendor.js:35358:19)
  at Class.get (http://localhost:4200/assets/vendor.js:49734:38)
  at Object.<anonymous> (http://localhost:4200/assets/tests.js:20126:25)
  at runTest (http://localhost:4200/assets/test-support.js:2779:28)
  at Object.run (http://localhost:4200/assets/test-support.js:2764:4)
  at http://localhost:4200/assets/test-support.js:2906:11
  at process (http://localhost:4200/assets/test-support.js:2565:24)

Which make senses. What is the best way to do it ? Should I create a DS.Model within the test and then apply the mixin on it ?

Thanks !

like image 234
ThomasDurin Avatar asked Sep 20 '16 12:09

ThomasDurin


People also ask

How do I run a test in Ember?

How to Run Your Tests. Run your tests with ember test on the command-line. You can re-run your tests on every file-change with ember test --server . Tests can also be executed when you are running a local development server (started by running ember server ), at the /tests URI which renders the tests/index.

What is mixin in Ember JS?

The Mixin class allows you to create mixins, whose properties can be added to other classes. For instance, 1 2 3 4 5 6 7 8 9. import Mixin from '@ember/object/mixin'; const EditableMixin = Mixin.create({ edit() { console.log('starting to edit'); this.set('isEditing', true); }, isEditing: false });


1 Answers

Unit testing a model mixin like this is a little tricky since it needs access to the store in order to create the model. Usually, the store is not available in mixin tests because there isn't even a container. Additionally, since we just want to test the mixin, we don't want to require a real model, so we can create and register a phony host model just for the tests. Here's how I did this.

First, pull in 'ember-data' and use the helpers from 'ember-qunit' instead of the stock helpers from 'qunit'. Replace this:

import { module, test } from 'qunit';

With this:

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

Then, you update your module declaration like this:

moduleFor('mixin:my-model-mixin', 'Unit | Mixin | my model mixin', {
  // Everything in this object is available via `this` for every test.
  subject() {
    // The scope here is the module, so we have access to the registration stuff.
    // Define and register our phony host model.
    let MyModelMixinObject = DS.Model.extend(MyModelMixin);
    this.register('model:my-model-mixin-object', MyModelMixinObject);

    // Once our model is registered, we create it via the store in the
    // usual way and return it. Since createRecord is async, we need
    // an Ember.run.
    return Ember.run(() => {
      let store = Ember.getOwner(this).lookup('service:store');
      return store.createRecord('my-model-mixin-object', {});
    });
  }
});

Once you have this setup in place, you can then use this.subject() in individual tests to get an object for testing.

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

At this point, it's just a standard unit test. You may need to wrap async or computed code in an Ember.run block:

test('it doubles the value', function(assert) {
  assert.expect(1);
  var subject = this.subject();
  Ember.run(() => {
    subject.set('someValue', 20);
    assert.equal(subject.get('twiceSomeValue'), 40);
  });
});
like image 193
tommyjr Avatar answered Sep 21 '22 17:09

tommyjr