在Ember路由单元测试中如何存根setupController然后测试路由方法

时间:2015-12-14 12:50:47

标签: unit-testing ember.js

我有一条没有明确创建控制器文件的路由。我的路线看起来像:

import Ember from 'ember';
import ApplicationRouteMixin from 'ember-simple-auth/mixins/application-route-mixin';
import vibrate from '../utils/utility-vibrate';

export default Ember.Route.extend(ApplicationRouteMixin, {
  setupController: function(controller, model) {
    this._super(controller, model);

    controller.set('session', Ember.inject.service('session'));

    controller.set('leftSidebarWidgets', []);
    controller.set('rightSidebarWidgets', []);
    controller.set('unpricedOrders', []);
    controller.set('loadingUnpricedOrders', {value: true});
  },
  deleteRecordValidation: function(modelName) {
    if (!modelName) {
      return true;
    }

    if (modelName === 'orderItem') {
      let rightHandWidgets = this.controller.get('rightSidebarWidgets');

      if (rightHandWidgets.any(w => Ember.get(w, 'name') === 'widgets/add-update-order-item')) {
        let orderItemDiv = Ember.$('.widgets\\/add-update-order-item');
        vibrate(orderItemDiv);

        return false;
      }
    }

    return true;
  }
  ...
});

然后我进行了单元测试:

import { moduleFor, test } from 'ember-qunit';

moduleFor('route:application', 'Unit | Route | application', {
  needs: ['service:session']
});

test('delete record validation returns false if order item delete and update order item widget open', function(assert) {
  assert.expect(1);

  let route = this.subject();

  route.controller.get('rightSidebarWidgets').insertAt(0, {
    name: 'widgets/add-update-order-item'
  });

  assert.notOk(route.deleteRecordValidation('orderItem'));
});

我正在尝试向控制器添加一些东西以测试特定场景 - 问题是测试随着Cannot read property 'get' of undefined而失效,因为route.controller为null。我是否需要存根设置控制器或其他东西以使'控制器'到位?如果是这样的话?

2 个答案:

答案 0 :(得分:2)

我将deleteRecordValidation函数更改为使用controllerFor('application')而不是this.controller。并且还将单元测试更新为:

controller:application

所以关键是要更改为ember g controller application并添加Attempting to register an unknown factory: 'controller:application'的需求。请注意,服务:会话一,因为我使用Ember Simple Auth。

有趣的是,我还必须{{1}}并保留默认值。没有这个,测试就失败了{{1}}。我已在Ember CLI的问题页面上发布,看看是否需要此步骤(https://github.com/ember-cli/ember-cli/issues/5217)。

答案 1 :(得分:2)

您实际上不需要存根setupController函数。除非你明确告诉它,否则这不会在你的单元测试中运行。但你确实需要模拟控制器本身。

首先,在您的测试文件中,创建一个模拟控制器:

let controller = Ember.Object.create();

如果要向此模拟对象添加字段,可以在创建时添加它们:

let controller = Ember.Object.create({
  someKey: someValue
});

或稍后添加:

controller.set('someKey', someValue);

您现在可以将此模拟控制器传递给setupController函数进行测试:

route.setupController(controller, model);

您可以将其分配到您的路线以测试您的deleteRecordValidation函数:

let route = this.subject({
  controller: controller
});

或者:

let route = this.subject();
route.controller = controller;

此时,您只需要将任何字段添加到它正在测试的方法中使用的模拟控制器。您可以覆盖大多数不是关联的东西。

与往常一样,最好在单元测试中模拟您正在测试的内容,因此这比导入实际控制器更好。

相关问题