使用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不是对象(评估'$('#login-form')[0] .submit')
我试过“通过间谍模拟”,使用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('login-form')
尝试了以下操作。但是,我得到TypeError: undefined is not a constructor (evaluating 'document.getElementById('login-form').submit()')
var mockElement = {
id:"login-form",
parentNode:true
};
var document_getElementById = document.getElementById;
var spy = spyOn(document, "getElementById").and.callFake(function(id){
if(id===mockElement.id){
return mockElement;
}
return document_getElementById(id);
});
答案 0 :(得分:2)
实际上,这是有效的。您将需要使用document.getElementById
来存根/间谍,因为这是jquery在引擎盖下使用的内容。我只是忘记了submit
函数的存根。我没有意识到这一点,因为茉莉花的包装错误是如此毫无意义。
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);
});