【问题标题】:Jasmine tests failing over EmberJS needs APIJasmine 测试失败 EmberJS 需要 API
【发布时间】:2013-03-21 12:51:43
【问题描述】:

我正在使用 Jasmine 对 EmberJS 项目进行单元测试,但在使用 Ember 的需求 API 时遇到问题。

当我尝试运行 jasmine 测试时,如果相关控制器具有“需求”以及调用

的 init 函数,它们将无法创建控制器实例

this._super()

我收到此控制台错误

"不能调用方法'has' of null"

当我尝试调试时,将我带入了 Ember 的内部,但我无能为力。

任何人都知道我做错了什么

Application.SearchPendingController = Ember.ObjectController.extend({
    needs: ['searchResults', 'search'],
    shouldDisable: false,
    searchResultsController: null,
    init: function () {
        this._super();

        this.set('searchResultsController', this.controllerFor('searchResults'));

        this.get('controllers.search.content').reload();

        this.get('controllers.searchResults').set('content', this.get('controllers.search.content.results'));

    },
    transitionToResults: function () {
        console.log('yay');
    }.observes('this.searchResultsController.content')
});

当我尝试创建此控制器时,jasmine 测试会引发错误

var searchPendingController = Application.SearchPendingController.create();

有人对此有任何想法吗?

【问题讨论】:

    标签: javascript unit-testing ember.js jasmine


    【解决方案1】:

    当您创建控制器时,Ember.js 在 init 方法中检查依赖项 (needs)。检查依赖项假设您有一个 Ember.js 应用程序,并且此应用程序的容器位于控制器的 container 属性中。如果 Ember.js 为您创建了控制器,这一切都很好。

    您的错误发生在here,在verifyDependencies 函数中。

    如果您不希望 Ember.js 为您创建控制器并希望手动创建它(这就是您在这里所做的),您需要手动将控制器的 container 属性设置为应用程序的容器。

    Application.SearchPendingController.reopen({
      container: Application.__container__
    });
    

    单元测试控制器很棘手,需要深入了解 Ember.js 的内部结构。我的建议是,让 Ember.js 为您创建控制器,并使用集成测试而不是单元测试。

    【讨论】:

    • 这对我来说非常有效(减去分号 :p )。非常感谢。
    • 谢谢。似乎是一个愚蠢的检查..这不应该是默认行为吗?我有一个视图,它在didInsertElement 上调用this.get('controller').domLoaded(),它实例化了有问题的控制器......我还认为我可以做this.set('childController', App.ChildController.createWithMixins({ container : this }),但这没有用......但是再次使用App.__container__ 工作...
    【解决方案2】:

    如果您的控制器需要访问另一个控制器以计算某些属性,则更好的是让容器为您创建控制器。

    Application.SearchPendingController = Ember.ObjectController.extend({
      needs: ['searchResults', 'search'],
    

    测试

      var searchModel = something, 
        searchResultsModel = something, 
        searchPendingModel = something;
    
    var container = Application.__container__,
      searchController = container.lookup('controller:search'),
      searchResultsController = container.lookup('controller:searchResults'),
      searchPendingController = container.lookup('controller:searchPending'),
      searchController.set('model', searchModel),
      searchResultsController.set('model', searchResultsModel ),
      searchPendingController.set('model', searchPendingModel );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-13
      • 1970-01-01
      • 2018-04-11
      • 2021-12-08
      • 1970-01-01
      • 2016-08-22
      • 2017-12-25
      • 1970-01-01
      相关资源
      最近更新 更多