我对AngularJs有点新鲜。我正在使用Angular UI bootstrap(0.10.0)进行模态实现。我在测试模态控制器时遇到以下错误
使用AngularJs 1.2.7:TypeError:尝试分配给只读属性
使用AngularJs 1.2.12:未知提供者:$ modalInstanceProvider< - $ modalInstance。
我经历了很多类似的问题,但无法理解问题是什么。
正如Mahery的评论所指出的那样,$ modalInstance可通过AngularUI Bootstrap实现在控制器中注入。因此,我们不需要任何努力来“解决”或以某种方式使其可用。 Modal Window Issue (Unknown Provider: ModalInstanceProvider)
这是我的主控制器,导致在点击部分页面上的open
时创建模态实例。
var SomeCtrl = function($scope, $modal){
$scope.open = function(){
$scope.modalInstance = $modal.open({
templateUrl: '/templates/simpleModal.html',
controller: 'simpleModalController',
});
$scope.modalInstance.result.then(
function(){
console.log("clicked OK");
},
function(){
console.log("clicked Cancel");
});
};
};
someCtrl.$inject = ["$scope", "$modal"];
angular.module('angularApp').controller("someCtrl", SomeCtrl);
这是模态控制器我希望测试它是否包含必要的功能(我打算稍后添加)
(function(){
var SimpleModalController = function($scope, $modalInstance){
$scope.ok = function(){
$modalInstance.close('ok');
};
$scope.cancel = function(){
$modalInstance.dismiss('cancel');
};
};
SimpleModalController.$inject = ["$scope", "$modalInstance"];
angular.module('angularApp').controller("simpleModalController", SimpleModalController);
})();
这是我为模态控制器编写的测试
describe('Testing simpleModalController',function() {
var ctrlScope;
var modalInstance;
var ctrl;
beforeEach(function() {
module('angularApp');
inject(function($rootScope, $modalInstance, $controller) {
ctrlScope = $rootScope.new();
modalInstance = $modalInstance;
ctrl = $controller('simpleModalController',
{
$scope : ctrlScope,
$modalInstance : modalInstance
});
});
});
it('should check existence of scope variables and functions when created', function() {
console.log('pending test');
});
});
我在app中的模态功能,测试主控制器和模态集成方面没有任何麻烦。但我无法测试模态控制器。我认为问题是在测试(简单模态控制器)中注入$ modalInstance。但正如前面提到的,angular-ui bootstrap使它可用。
感谢任何帮助。感谢。
答案 0 :(得分:1)
拥有下一个模态控制器定义:
Intent intent = new Intent(this, HomeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("Exit", true);
startActivity(intent);
finish();
您可以使用jasmine使用所需方法创建间谍对象,并在创建实例时将该对象传递给控制器:
OnCreate()
稍后在测试场景中,您可以检查间谍对象:
if( getIntent().getBooleanExtra("Exit", false)){
finish();
}
答案 1 :(得分:0)
我也一直在与这个问题作斗争。问题是你试图在测试中实例化的控制器是一个完全不同的实例,$ modal服务实例化在内部传递实际模态窗口为$ modalInstance。请参阅示例http://angular-ui.github.io/bootstrap/#/modal中的js代码注释:
// Please note that $modalInstance represents a modal window (instance) dependency.
// It is not the same as the $modal service used above.
那么你如何测试你的控制器呢?我还没有找到解决方案,对不起。由于$ modal服务根据$ rootScope或您传入选项的范围创建新范围,因此难以实现您无法访问控制器范围。所以你松开了轨道。
您可以做的最少的事情是测试传递给结果承诺的函数。这是通过监视$ modal.open函数并返回一个mock来完成的。这里显示https://stackoverflow.com/a/21370703/2202143。并使用量角器等工具补充集成测试。
答案 2 :(得分:0)
所以..这是测试它的一种方式..
describe('Testing',function() {
it('test',function() {
inject(function($rootScope, $modal) {
var fakeModal = { };
//Basically, what you want is for your modal's controller to get
//initalized and then returned to you, so the methods in it can be unit tested
spyOn(modal, 'open').andReturn(fakeModal);
ctrl = $controller('Controller',
{
$scope : ctrlScope,
$modal: modal
});
});
});
});
答案 3 :(得分:0)
查看问题所选答案的正确答案:Unit testing a modalInstance controller with Karma / Jasmine。
我在同一个问题上挣扎了一段时间,这个问题(和答案)帮助我以一种非常干净的方式测试我的模态(以及打开/关闭它们的功能)!
答案 4 :(得分:0)
我不喜欢这里给出的任何答案所以我正在添加自己的答案。
我之所以不喜欢上述答案的原因是,一旦项目变得更大,他们就不会坚持。
对我来说,解决方案是简单地实现名为$ modalInstance ...
的角度服务所以在spec
下,我创建了一个名为shims
的文件夹,我将其用于这些小项目。 (确保将其添加到karma.conf
)
我在那里实施
angular.module(..).service('$modalInstance', function(){
this.dismiss = jasmine.createSpy('$modalInstance.dismiss');
...
});
我发现这种方法更清洁,更易于维护和简单。
有时,我喜欢确保我的垫片仅为特定测试加载,在这种情况下,我只是给它一个特定的模块名称然后我必须为它添加module
调用,否则它会赢得'加载。
我也强烈建议使用不同的库作为模态,我推荐使用ng-dialog有很多原因,但在这种情况下,我可以说它更适合测试,现在已经使用了一段时间了。