Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/416.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/80.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 如何对包含DOM/jquery选择器的Angular 1控制器进行单元测试?_Javascript_Jquery_Angularjs_Unit Testing_Jasmine - Fatal编程技术网

Javascript 如何对包含DOM/jquery选择器的Angular 1控制器进行单元测试?

Javascript 如何对包含DOM/jquery选择器的Angular 1控制器进行单元测试?,javascript,jquery,angularjs,unit-testing,jasmine,Javascript,Jquery,Angularjs,Unit Testing,Jasmine,使用jasmine时,我似乎无法测试一个包含jquery选择器或document.getElementById的函数。这里有更好的策略吗?我通常不把选择器放在角度代码中,不过这是一个解决办法 在我正在测试的函数中: this.scope.login = () => { ($('#login-form')[0] as HTMLFormElement).submit(); // or even document.getElementById('login-form').submit

使用jasmine时,我似乎无法测试一个包含jquery选择器或
document.getElementById
的函数。这里有更好的策略吗?我通常不把选择器放在角度代码中,不过这是一个解决办法

在我正在测试的函数中:

this.scope.login = () => {

 ($('#login-form')[0] as HTMLFormElement).submit(); 
 // or even 
 document.getElementById('login-form').submit(); // this is a workaround for browser auto-complete, I normally would not have selectors in angular code.
}
我明白了

TypeError:undefined不是对象(计算“$”(“#登录表单”)[0]。提交“)

我尝试过“通过间谍进行模拟”,使用spyOn尝试模拟jquery选择器函数并返回一个伪元素。。。但似乎不起作用,或者我做得不对

我的等级库加载模板(日志正常)。元素也已定义,并且似乎是有效的角编译元素

describe('Nav Controller Spec', function() {

beforeEach(function() {
  angular.mock.module('App');

  inject(function(_$controller_, $rootScope, _userModel_, _$q_, _$httpBackend_, $templateCache, _$compile_) {

    scope = $rootScope.$new();
    $q = _$q_;
    $compile = _$compile_;
    $httpBackend = _$httpBackend_;
    deferred = _$q_.defer();

    html = $templateCache.get('main/components/login/login.tpl.html');
    var el = angular.element( html );
    element = $compile( el )(scope); //element is valid and works

    controller = _$controller_;
    userModel = _userModel_;

    scope.userModel = userModel;

    // tried this... still get error
    spyOn($.fn, 'val').and.returnValue('<form></form>');

    //if i change to 'init' or 'find', i get 'undefined is not a constructor'
    spyOn($.fn, 'init').and.returnValue('<form></form>');

    ctrl = controller('loginController', { $scope: scope, $element: element });

    $rootScope.$digest();
  });

});

it('should login and change the status', function(){
   spyOn(  ctrl.scope.userModel, 'login' ).and.callThrough();
   ctrl.scope.formType = 'login';
   ctrl.scope.login(); //fails
   expect( ctrl.scope.userModel.login ).toHaveBeenCalled();
});

实际上,这是可行的。您需要使用
document.getElementById
来存根/监视,因为jquery在引擎盖下使用的是存根/间谍。我只是忘了将
submit
函数存根。我没有意识到这一点,因为jasmine的包装错误是如此毫无意义

      var mockElement = {
        id:"login-form",
        parentNode:true,
         submit:function(){
           return 'cheese';
         }
      };
      var document_getElementById = document.getElementById;
      var spy = spyOn(document, "getElementById").and.callFake(function(id){
        if(id===mockElement.id){
          return mockElement;
        }
        return document_getElementById(id);
      });

实际上,这是可行的。您需要使用
document.getElementById
来存根/监视,因为jquery在引擎盖下使用的是存根/间谍。我只是忘了将
submit
函数存根。我没有意识到这一点,因为jasmine的包装错误是如此毫无意义

      var mockElement = {
        id:"login-form",
        parentNode:true,
         submit:function(){
           return 'cheese';
         }
      };
      var document_getElementById = document.getElementById;
      var spy = spyOn(document, "getElementById").and.callFake(function(id){
        if(id===mockElement.id){
          return mockElement;
        }
        return document_getElementById(id);
      });