测试模式控制器:未知提供程序:$modalInstanceProvider <- $modalInstance,类型错误:尝试分配给只读属性



我对AngularJs有点陌生。我使用Angular UI引导程序(0.10.0)进行模式实现。我在使用AngularJs 1.2.7测试模态控制器时遇到以下错误:类型错误:试图使用AngularJ s 1.2.12分配给只读属性
:未知提供程序:$modalInstanceProvider<-$modalInstance。

我经历了很多类似的问题,但不明白问题出在哪里。

正如Mahery在评论中指出的,$modalInstance可通过AngularUI Bootstrap实现在控制器中注入。因此,我们不需要任何努力来"解决"或以某种方式使其可用。模式窗口问题(未知提供程序: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');
});
});

我在应用程序中的modal功能、测试主控制器和modal的集成方面没有遇到任何问题。但我无法测试模态控制器。我认为问题是在测试中注入$modalInstance(简单模态控制器)。但如前所述,angular ui bootstrap使其可用。

感谢您的帮助。谢谢

拥有下一个模态控制器定义:

angular.module('module').controller('ModalInstanceController',ModalInstanceController);
function ModalInstanceController($timeout, $modalInstance, $scope) {
//controller across a bunch of modals
$scope.closeModal = function(){
$modalInstance.dismiss('cancel');
};
$scope.action = function(){
$modalInstance.dismiss();
};
}

您可以使用jasmine使用所需的方法创建一个spy对象,并在创建实例时将该对象传递给控制器:

beforeEach(inject(($controller, $timeout, $rootScope) => {
modalInstance = jasmine.createSpyObj('modalInstance', ['dismiss']);
scope = $rootScope.$new();
controller = $controller('ModalInstanceController', {
$modalInstance: modalInstance,
$scope: scope
});
}));

稍后在测试场景中,您可以检查被监视的对象:

it('should defined the required methods on the scope', () => {
expect(scope.closeModal).toBeDefined();
expect(scope.action).toBeDefined();
scope.closeModal();
expect(modalInstance.dismiss).toHaveBeenCalledWith('cancel');
scope.action();
expect(modalInstance.dismiss).toHaveBeenCalledWith();
});

所以。。这是一种测试方法。

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
}); 
});
});
});

我也一直在与这个问题作斗争。问题是,您试图在测试中实例化的控制器是一个完全不同的实例,$modal服务实例化的控制器在实际模态窗口中作为$modalInstance内部传递。请参阅示例中的js代码注释http://angular-ui.github.io/bootstrap/#/modal:

// 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.并使用量角器等工具进行集成测试。

看看问题上被选为正确的答案:用Karma/Jastsmine对modalInstance控制器进行单元测试。

我在同一个问题上挣扎了一段时间,这个问题(和答案)帮助我以一种非常干净的方式测试了我的模态(以及打开/关闭它们的功能)!

我不喜欢这里给出的任何答案,所以我添加了自己的答案。

我不喜欢上面的答案的原因是,一旦一个项目变得更大,它们就不成立了。

对我来说,解决方案是简单地实现一个名为$modalInstance的角度服务。。。

所以在CCD_ 2下,我创建了一个名为CCD_。(确保将其添加到karma.conf)

在那里我实现了

angular.module(..).service('$modalInstance', function(){
this.dismiss = jasmine.createSpy('$modalInstance.dismiss'); 
... 
});

我发现这种方法更干净、更易于维护、更简单。

有时,我喜欢确保我的填充程序只为特定的测试加载,在这种情况下,我只需给它一个特定的模块名称,然后我必须为它添加一个module调用,否则它将无法加载。

我也强烈建议使用不同的模态库,我推荐ng-dialog有很多原因,但在这种情况下,我可以说它对测试更友好,已经使用了一段时间了。

最新更新