且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何使用this.get('store')单元测试控制器

更新时间:2023-09-28 17:51:28

控制器从容器访问商店。您可以创建一个模拟容器并使用它来实例化控制器。

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

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

如果您需要访问真正的商店然后你可以从你的应用程序的容器中抓取控制器。

  var controller = App .__ container __。lookup('controller:post'); 

一个 PostController 为您拥有连接在一起的所有依赖关系(如商店)。


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
        }}});

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.