Deewendra Shrestha
Deewendra Shrestha

Reputation: 2465

how to unit test controller which uses this.get('store')

I am unit testing my controller using mocha. My controller looks like:

AS.MyController = Ember.ObjectController.extend(Ember.Validations.Mixin, {

    name: null,
    description: null,

    init: function () {
        this._super();

        this.get('store').find('something');
    },
    ....
}); 

And my test begins like:

describe("MyControllerTest", function () {
    //tried but didn't work
    //delete AS.MyController.init;
    var controller = AS.MyController.create();
    .....
})  

and the browser always throws error on "this.get('store')" call in init. I am not sure if I need to stub things out or there is a work around for it because my test case doesn't rely on store at all. In either case, I couldn't find much out there and would really appreciate any feedback.

Thanks, Dee

JSBIN : http://jsbin.com/aMASeq/3/

UPDATE : There can be many ways to tackle this issue, but what I ended up doing is re-structuring the controller code a bit by putting all the function calls to store into separate actions and then in init I make calls to these action functions using this.send('actioName'). In my unit test, before instantiating the controller, I reopen the controller to modify these action functions(its easier to change action function than to change init function itself, when trying to change init I always got into some js error). Eg:

AS.MyController.reopen({actions: {setSomeActionThatUsesStore: function () {
         //do something that doesn't involve using store
        }}});

Upvotes: 1

Views: 2183

Answers (1)

Ryan
Ryan

Reputation: 3594

Controllers get access to the store from the container. You can create a mock container and instantiate the controller with it.

var mockContainer = new Ember.Container();
mockContainer.register('store:main', Ember.Object.extend({ 
  find: function() { ... }
});

var controller = App.PostController.create({ container: mockContainer });

If you need access to the real store then you can just grab the controller from your App's container.

var controller = App.__container__.lookup('controller:post');

That will instantiate a PostController for you that has all of it's dependencies (such as store) wired together.

Upvotes: 2

Related Questions