我有一条没有明确创建控制器文件的路由。我的路线看起来像:
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。我是否需要存根设置控制器或其他东西以使'控制器'到位?如果是这样的话?
答案 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;
此时,您只需要将任何字段添加到它正在测试的方法中使用的模拟控制器。您可以覆盖大多数不是关联的东西。
与往常一样,最好在单元测试中模拟您正在测试的内容,因此这比导入实际控制器更好。