Testing AngularUI Bootstrap modal instance controller

后端 未结 4 715
醉话见心
醉话见心 2020-12-05 07:32

This is a somewhat of a follow-on question to this one: Mocking $modal in AngularJS unit tests

The referenced SO is an excellent question with very useful answer. Th

相关标签:
4条回答
  • 2020-12-05 07:33

    Alternatively, if you're using jasmine, you can mock the $uibModalInstance using the createSpy method:

    beforeEach(inject(function ($controller, $rootScope) {
      $scope = $rootScope.$new();
      $uibModalInstance = jasmine.createSpyObj('$uibModalInstance', ['close', 'dismiss']);
    
      ModalCtrl = $controller('ModalCtrl', {
        $scope: $scope,
        $uibModalInstance: $uibModalInstance,
      });
    }));
    

    And test it without having to call spyOn on each method, let's say you have 2 scope methods, cancel() and confirm():

    it('should let the user dismiss the modal', function () {
      expect($scope.cancel).toBeDefined();
      $scope.cancel();
      expect($uibModalInstance.dismiss).toHaveBeenCalled();
    });
    
    it('should let the user confirm the modal', function () {
      expect($scope.confirm).toBeDefined();
      $scope.confirm();
      expect($uibModalInstance.close).toHaveBeenCalled();
    });
    
    0 讨论(0)
  • 2020-12-05 07:37

    Follow below given steps:

    • Define stub for ModalInstance like give below

              uibModalInstanceStub = {
                  close: sinon.stub(),
                  dismiss: sinon.stub()
              };
      
    • Pass the modal instance stub while creating controller

          function createController() {
              return $controller(
                  ppcConfirmGapModalComponentFullName,
                  {
                      $scope: scopeStub,
                      $uibModalInstance: uibModalInstanceStub
                  });
          }
      });
      
    • Stub methods close(), dismiss() will get called as part of the tests

      it('confirm modal - verify confirm action, on ok() call calls modalInstance close() function', function() { action = 'Ok'; scopeStub.item = testItem; createController(); scopeStub.ok(); });

    0 讨论(0)
  • 2020-12-05 07:39

    The same problem is with $uidModalInstance and you can solve it in similar way:

    var uidModalInstance = { close: function() {}, dismiss: function() {} };
    
    $ctrl = $controller('ModalInstanceCtrl', {
       $scope: $scope,
       $uibModalInstance: uidModalInstance
    });
    

    or as said @yvesmancera you can use jasmine.createSpy method instead, like:

    var uidModalInstance = jasmine.createSpyObj('$uibModalInstance', ['close', 'dismiss']);
    
    $ctrl = $controller('ModalInstanceCtrl', {
       $scope: $scope,
       $uibModalInstance: uidModalInstance
    });
    
    0 讨论(0)
  • 2020-12-05 07:59

    I test the controllers used in modal dialogs by instantiating the controller directly (the same way you initially thought to do it above).

    Since there there's no mocked version of $modalInstance, I simply create a mock object and pass that into the controller.

    var modalInstance = { close: function() {}, dismiss: function() {} };
    var items = []; // whatever...
    
    beforeEach(inject(function($rootScope) {
      scope = $rootScope.$new();
      ctrl = $controller('ModalInstanceCtrl', {
          $scope: scope, 
          $modalInstance: modalInstance, 
          items: items
      });
    }));
    

    Now the dependencies for the controller are satisfied and you can test this controller like any other controller.

    For example, I can do spyOn(modalInstance, 'close') and then assert that my controller is closing the dialog at the appropriate time.

    0 讨论(0)
提交回复
热议问题