11
votes

According to the blog-post for ember-data version 1.0.0-beta.16 the store can now be used as a service:

TweetComposerComponent = Ember.Component.extend({
  store: Ember.inject.service()      
});

However, I can't figure out how to do qunit unit tests on such a component. I've tried the following:

moduleForComponent('tweet-composer', {
  needs: ['service:store']
});

and:

moduleForComponent('tweet-composer', {
  needs: ['store:main']
});

And when I do the former I get an error Attempting to register an unknown factory: 'service:store' and if I do the latter then store is undefined.

Thoughts?

(I'm writing a ember-cli style app).

Update:

It seems there's an open issue for this in the ember-test-helpers repo.

While I'm waiting for this fix, I cooked up a helper that can work as a stop-gap measure (coffeescript):

`import TestModuleForComponent from 'ember-test-helpers/test-module-for-component'`
`import { createModule } from 'ember-qunit/qunit-module'`

# This assumes the last argument, the callbacks, is present, although it
# does support the description being an optional argument.
moduleForStoreComponent = ->
  args = Array.prototype.slice.call arguments
  callbacks = args[args.length-1]
  # Wrap the original beforeEach callback in a modified version that
  # also sets up the store for the test container.
  originalSetup = callbacks.beforeEach
  callbacks.beforeEach = ->
    DS._setupContainer(@container)
    originalSetup.call(@) if originalSetup
  callbacks.store = ->
    @container.lookup('store:main')
  args.unshift TestModuleForComponent
  createModule.apply @, args

`export default moduleForStoreComponent`
1

1 Answers

13
votes

A unit test is a place where everything works perfectly except the code/component/unit that you are testing.

So, even the store should be assumed to be working perfectly (0 errors/bugs).

Something like this should work in your test:

moduleForComponent('tweet-composer', {
    beforeEach: function() {
        this.subject({
            store: {/*empty object*/}
        });
    }
});

If parts of your tests depend on data retrieved from the store, you can do something like:

this.subject({
    store: {
        find: function() {
          var mockedModel = Ember.Object.create({/*empty*/});
          return mockedModel;
        }
    }
});

This is to preserve the status of "unit test", if you start including and registering other objects from your app you 'll be actually writing integration tests.

Note:

In general, looking up models directly in a component is an anti-pattern, and you should prefer to pass in any model you need in the template that included the component.

http://discuss.emberjs.com/t/should-ember-components-load-data/4218/2?u=givanse