ern*_*ejo 30 unit-testing angularjs
我在一个指令中使用bindToController让隔离的作用域直接连接到控制器,如下所示:
app.directive('xx', function () {
return {
bindToController: true,
controller: 'xxCtrl',
scope: {
label: '@',
},
};
});
Run Code Online (Sandbox Code Playgroud)
然后在控制器中我有一个默认情况下,HTML中没有指定标签:
app.controller('xxCtrl', function () {
var ctrl = this;
ctrl.label = ctrl.label || 'default value';
});
Run Code Online (Sandbox Code Playgroud)
如何在Jasmine单元测试中实例化xxCtrl,以便我可以测试ctrl.label?
describe('buttons.RemoveButtonCtrl', function () {
var ctrl;
beforeEach(inject(function ($controller) {
// What do I do here to set ctrl.label BEFORE the controller runs?
ctrl = $controller('xxCtrl');
}));
it('should have a label', function () {
expect(ctrl.label).toBe('foo');
});
});
Run Code Online (Sandbox Code Playgroud)
选中此项以测试问题
mey*_*tee 47
在Angular 1.3中(见下面的1.4+)
深入研究AngularJS源代码,我发现了一个未记录的$controller服务的第三个参数later(参见$ controller source).
如果为true,则$controller()返回具有可instance在其上设置属性的属性的Function .
当您准备好实例化控制器时,调用该函数并使用构造函数中可用的属性实例化控制器.
你的例子会像这样工作:
describe('buttons.RemoveButtonCtrl', function () {
var ctrlFn, ctrl, $scope;
beforeEach(inject(function ($rootScope, $controller) {
scope = $rootScope.$new();
ctrlFn = $controller('xxCtrl', {
$scope: scope,
}, true);
}));
it('should have a label', function () {
ctrlFn.instance.label = 'foo'; // set the value
// create controller instance
ctrl = ctrlFn();
// test
expect(ctrl.label).toBe('foo');
});
});
Run Code Online (Sandbox Code Playgroud)
这是一个更新的Plunker(必须升级Angular使其工作,现在是1.3.0-rc.4):http://plnkr.co/edit/tnLIyzZHKqPO6Tekd804?p = preview
请注意,可能不建议使用它,引用Angular源代码:
稍后实例化控制器:此机制用于在调用控制器的构造函数本身之前创建对象的实例.
这允许在调用构造函数之前将属性添加到控制器.主要是,它用于$ compile中的隔离范围绑定.
此功能不适用于应用程序,因此不会公开记录.
然而,缺乏一种测试控制器的机制bindToController: true让我使用它.也许Angular家伙应该考虑将该旗帜公之于众.
在引擎盖下它使用临时构造函数,我们也可以自己编写它.
您的解决方案的优点是构造函数不会被调用两次,如果属性没有示例中的默认值,则可能会导致问题.
Angular 1.4+(2015-12-06更新):
Angular团队在版本1.4.0中添加了对此的直接支持.(参见#9425)
您可以将对象传递给$controller函数:
describe('buttons.RemoveButtonCtrl', function () {
var ctrl, $scope;
beforeEach(inject(function ($rootScope, $controller) {
scope = $rootScope.$new();
ctrl = $controller('xxCtrl', {
$scope: scope,
}, {
label: 'foo'
});
}));
it('should have a label', function () {
expect(ctrl.label).toBe('foo');
});
});
Run Code Online (Sandbox Code Playgroud)
另请参阅此博客文章.
| 归档时间: |
|
| 查看次数: |
5750 次 |
| 最近记录: |