如何在茉莉花中对$uibModal进行单元测试?(单元测试注入库)



所以我正在使用引导程序的$uibModal,我的AngularJS控制器中有以下代码:

vm.openPopup = function() {
$uibModal.open({
templateUrl: 'popup.html',
controller: function() {
var modal = this;
modal.hi = function() {
// some code here
}
}
});
};

我将如何在Jasmine中调用modal.hi函数并对其进行单元测试以确保其正常工作?

所以测试这段代码的主要问题是你基本上已经"埋藏"了一个匿名函数(modal.hi)在另一个匿名函数($uibModal.open)中。这使得测试变得非常棘手。

您有几种选择:a.) 您可以模拟$uibModal服务,b.)您可以重新构建代码,或 c.)您可以将hi函数放到vm本身上,然后从测试中调用它。我认为最后一个选项是最方便的,但这里有所有三种方法的一些例子。

选项 1:模拟$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函数来自角度模拟,您需要将其安装/包含在测试中。相关问题:"当使用 jasmine 进行单元测试时,您如何模拟 AngularJS 中的服务?

选项 2:重构代码

这是我经常使用的一种模式,它涉及将您希望测试的逻辑/函数转移到单独的工厂中:

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服务。这通常是我最喜欢的方法:没有内联/匿名函数 - 将该逻辑放入帮助程序工厂和我的控制器中。

选项 3:将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对象添加控制器作用域中实际上不需要的任何属性。但在这种情况下,我们打破了该规则,因为这是"公开"您希望测试的此函数的最快/最简单的方法。

最新更新