Vamshi Suram Vamshi Suram - 3 months ago 13
AngularJS Question

Testing Modal Controller: unknown provider: $modalInstanceProvider <- $modalInstance, TypeError: Attempted to assign to a readonly property

I am a bit new to AngularJs. I am using Angular UI bootstrap (0.10.0) for modal implementation. I am getting the following errors while testing a modal controller

using AngularJs 1.2.7: TypeError: Attempted to assign to a readonly property

using AngularJs 1.2.12: unknown provider: $modalInstanceProvider <- $modalInstance.

I have gone through a lot of similar questions but couldn't understand what's the problem.


As pointed in the comments by Mahery, $modalInstance is made available for injection in the controller by AngularUI Bootstrap implementation. So, we don't need any effort to "resolve" or make it available somehow.
Modal Window Issue (Unknown Provider: ModalInstanceProvider)





This is my main controller that leads to creation of modal instance on clicking
open
on the partial page.


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






This is the modal controller I wish to test if it contains the necessary functions (which I intend to add later)


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

})();





This is the test I have written for the modal controller


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


I have no troubles in the functionality of modal in the app, testing the main controller and integration of modal. But I am unable to test the modal controller. I think the problem is with injection of $modalInstance in the test (of simple modal controller). But as mentioned earlier, angular-ui bootstrap makes it available.

Any help is appreciated. Thanks.

Answer

So.. This is one way of testing it..

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