Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing a Model Mixin

I'm trying to do a basic "it works" test for a Mixin which is meant to be used with a Model. I assume the approach to unit testing the Mixin should be done not on the Mixin itself but a generic Model class which has this Mixin mixed in.

Assuming this first assumption/strategy makes sense then here's what I have tried doing:

import DS from 'ember-data';
import Ember from 'ember';
import DictionaryManagerMixin from 'trainer/mixins/dictionary-manager';

module('DictionaryManagerMixin');

test('it works', function() {
  var DictionaryManagerModel = DS.Model.extend(DictionaryManagerMixin, {
      title: DS.attr('string')
  });
  var myStore = DS.Store.create();
  var subject = myStore.createRecord(DictionaryManagerModel);
  ok(subject);
});

This doesn't work, giving the following error:

TypeError: Cannot read property 'lookup' of undefined
    at null.<anonymous> (http://localhost:4200/assets/vendor.js:95610:35)
    at Descriptor.ComputedPropertyPrototype.get (http://localhost:4200/assets/vendor.js:28466:25)
    at get (http://localhost:4200/assets/vendor.js:33944:21)
    at Ember.Object.extend.adapterFor (http://localhost:4200/assets/vendor.js:97005:27)
    at Ember.Object.extend._generateId (http://localhost:4200/assets/vendor.js:95682:28)
    at Ember.Object.extend.createRecord (http://localhost:4200/assets/vendor.js:95654:32)
    at Object.eval (trainer/tests/unit/mixins/dictionary-manager-test.js:17:28)
    at Object.Test.run (http://localhost:4200/assets/test-support.js:2632:18)
    at http://localhost:4200/assets/test-support.js:2719:10
    at process (http://localhost:4200/assets/test-support.js:2435:24)

Any help would be greatly appreciated.

like image 207
ken Avatar asked Dec 14 '14 00:12

ken


1 Answers

Usually lookup requires a container, so that's a hint to what I'm thinking is causing the problem. This makes sense because DS relies on a container to be able to look up registered models at model:model-name;

So your test dependency for this mixin is really on Ember Data being setup properly. So if you your test so that it works for an Ember Data model, the mixin more or less just falls into place with the object setup how it expects.

I would say try using moduleForModel, from the useful Ember doc:

moduleForModel('dictionary-manager-model');

test('your test here', function(assert) {
    // this.subject aliases the createRecord method on the model
    const dictionaryManagerModel = this.subject();
});

Do you need to conditionally roll in the mixin with the model? If your model always uses the mixin, you could do it in the model definition file and just test it as shown above. In your example the mixin is being added to the model and the model is being passed to createRecord` but this isn't encouraged:

https://github.com/emberjs/data/blob/v2.14.10/addon/-private/system/store.js#L351 assert(Passing classes to store methods has been removed. Please pass a dasherized string instead of ${modelName}, typeof modelName === 'string'); which is why we rely on the lookup on the container.

Essentially, I think you are after a Model test, not a mixin test. Unless the mixin can be rolled into something that is not a model and still work.

ember generate model-test dictionary-manager-model if it doesn't exist already, and then your model file has the mixin already mixed into it. Also, maybe this doesn't need to be a separate mixin?

Hope this gets you started in the right direction, cheers! ✌🏽

like image 163
Chad Carbert Avatar answered Nov 12 '22 13:11

Chad Carbert