Javascript 如何对包含DOM/jquery选择器的Angular 1控制器进行单元测试?
使用jasmine时,我似乎无法测试一个包含jquery选择器或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
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);
});