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 !
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.
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 });
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);
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With