所以我从引导程序中使用$ uibModal,并且在AngularJS控制器中有以下代码:
{{1}}
我该如何在Jasmine中调用modal.hi函数并进行单元测试以确保其正常工作?
答案 0 :(得分:1)
因此测试此代码的主要问题是,您基本上已经将“匿名”函数(modal.hi
埋在了另一个匿名函数($uibModal.open
)内部。这使得测试非常棘手。
您有一些选择:a。)您可以模拟$uibModal
服务,b。)您可以重构代码,或者c。)您可以将hi
函数放到vm
本身,然后从测试中调用它。我认为最后一种选择是最方便的选择,但这是这三种方法的一些示例。
$uibModal
服务describe('Test vm.openPopup', function () {
var mockUibModal = {
open: function(options){
var ctrl = options.controller();
// call your `hi` function:
ctrl.hi();
}
};
beforeEach(function(){
module(function($provide){
$provide.value('$uibModal', mockUibModal);
});
});
});
从那里,您可以调用vm.openPopup
方法,然后测试结果。请注意,module
函数来自angular-mocks,您需要将其安装/包含在测试中。相关问题:“ How do you mock a service in AngularJS when unit testing with jasmine?”
这是我经常使用的一种模式,它涉及将要测试的逻辑/功能转移到单独的工厂中:
var app = angular.controller('YourController', function ($uibModal, MyHelperFactory) {
var vm = this;
var modal;
var helper = MyHelperFactory(vm, modal);
vm.openPopup = function () {
$uibModal.open({
templateUrl: 'popup.html',
controller: function () {
modal = this;
modal.hi = helper.hi;
}
});
};
});
app.factory('MyHelperFactory', function () {
return function (vm, modal) {
return {
hi: function () {
// some code here, maybe it needs to reference the `vm` object, whatever...
}
}
};
})
此方法的优点是您可以自己测试MyHelperFactory
,而无需实例化YourController
,也不需要涉及$uibModal
服务。通常,这是我最喜欢的方法:没有内联/匿名函数-将逻辑带入帮助程序工厂,并从我的控制器中移出。
hi
函数放到vm
var app = angular.controller('YourController', function ($uibModal, MyHelperFactory) {
var vm = this;
// this pattern allows your function to be scoped with the not-yet-existing `modal` object
vm.hi = function (modal) {
return function () {
// some code here
}
};
vm.openPopup = function () {
$uibModal.open({
templateUrl: 'popup.html',
controller: function () {
var modal = this;
modal.hi = vm.hi(modal);
}
});
};
});
从那里,您可以通过在测试中调用vm.hi
对其进行测试。我将此方法称为“肮脏”,因为它向hi
对象添加了vm
方法,并且我通常避免向控制器上实际不需要的vm
对象添加任何属性。范围。不过,在这种情况下,我们违反了该规则,因为它是“暴露”您要测试的功能的最快/最简单的方法。