Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/450.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 测试模态控制器:未知提供程序:$modalInstanceProvider<;-$modalInstance,TypeError:试图分配给只读属性_Javascript_Angularjs_Angular Ui Bootstrap_Angularjs Service - Fatal编程技术网

Javascript 测试模态控制器:未知提供程序:$modalInstanceProvider<;-$modalInstance,TypeError:试图分配给只读属性

Javascript 测试模态控制器:未知提供程序:$modalInstanceProvider<;-$modalInstance,TypeError:试图分配给只读属性,javascript,angularjs,angular-ui-bootstrap,angularjs-service,Javascript,Angularjs,Angular Ui Bootstrap,Angularjs Service,我对AngularJs有点陌生。我使用AngularUI引导(0.10.0)进行模式实现。我在测试模态控制器时遇到以下错误 使用AngularJs 1.2.7:TypeError:试图分配给只读属性 使用AngularJs 1.2.12:unknown provider:$modalInstanceProvider我也一直在与这个问题作斗争。问题在于,您试图在测试中实例化的控制器是完全不同的实例,$modal服务在内部实例化,并作为$modalInstance传递到实际的modal窗口中。请参见

我对AngularJs有点陌生。我使用AngularUI引导(0.10.0)进行模式实现。我在测试模态控制器时遇到以下错误
使用AngularJs 1.2.7:TypeError:试图分配给只读属性

使用AngularJs 1.2.12:unknown provider:$modalInstanceProvider我也一直在与这个问题作斗争。问题在于,您试图在测试中实例化的控制器是完全不同的实例,$modal服务在内部实例化,并作为$modalInstance传递到实际的modal窗口中。请参见示例中的js代码注释:

那么,如何测试控制器呢?对不起,我还没有找到解决办法。不同之处在于,您无法访问控制器的作用域,因为$modal服务根据$rootScope或随选项传入的作用域创建新的作用域。所以你失去了方向


您至少可以测试传递给结果的函数。这是通过监视$modal.open函数并返回模拟来完成的。这里显示了这一点。并使用诸如量角器之类的工具补充集成测试。

So。。这是测试它的一种方法

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

请查看在以下问题上选择为正确的答案:


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

我不喜欢这里给出的任何答案,因此我添加了我自己的答案

我不喜欢上面的答案的原因是,一旦一个项目大一点,它们就不起作用了

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

因此,在
spec
下,我创建了一个名为
shimmes
的文件夹,用于这些小项目。(确保将其添加到
karma.conf

在那里我实现了

angular.module(..).service('$modalInstance', function(){
     this.dismiss = jasmine.createSpy('$modalInstance.dismiss'); 
     ... 
});
我发现这种方法更简洁、更易于维护和直接

有时,我喜欢确保仅为特定测试加载垫片,在这种情况下,我只需给它一个特定的模块名,然后我必须为它添加一个
模块
调用,否则它不会加载


我还强烈建议使用不同的modals库,出于许多原因,我建议使用ng-dialog,但在这种情况下,我可以说它对测试更加友好,已经使用了一段时间了

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

  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
    });
  }));
稍后在测试场景中,您可以检查spied对象:

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

此代码不起作用,模态未定义,测试仍然失败。
angular.module(..).service('$modalInstance', function(){
     this.dismiss = jasmine.createSpy('$modalInstance.dismiss'); 
     ... 
});
  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();
    };
  }
 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();
  });