Javascript 如何使用spyOn模拟Jasmine中选择器的jQuery值?
我正在使用AngularJS/Karma/Jasmine编写一些单元测试,但无法让Jasmine的“spyOn”方法工作。在我使用Javascript 如何使用spyOn模拟Jasmine中选择器的jQuery值?,javascript,jquery,unit-testing,jasmine,karma-jasmine,Javascript,Jquery,Unit Testing,Jasmine,Karma Jasmine,我正在使用AngularJS/Karma/Jasmine编写一些单元测试,但无法让Jasmine的“spyOn”方法工作。在我使用spyOn之后,我仍然得到该选择器的undefined 问题 我遇到的问题是,在我跑步之后 spyOn($("#username"), "val").and.returnValue("test@test.com"); 我尝试获取用户名的值,如下所示: $("#username").val(); 而且它是未定义的 我想测试的代码 单元测试 有人看到我做错了什么吗?你
spyOn
之后,我仍然得到该选择器的undefined
问题
我遇到的问题是,在我跑步之后
spyOn($("#username"), "val").and.returnValue("test@test.com");
我尝试获取用户名的值,如下所示:
$("#username").val();
而且它是未定义的
我想测试的代码
单元测试
有人看到我做错了什么吗?你的问题是每次调用
$(“#用户名”)
时,你都会得到一个不同的对象。因此,函数中的$(“#用户名”)
将不会被监视
您应该监视所有jQuery对象共享的$.fn
spyOn($.fn, 'val').and.returnValue('test@test.com')
看起来相关:。这实际上不是另一个问题的完全重复,因为这个问题包括测试中的代码(CUT),即
isValidEmail
函数,而另一个问题没有。这一点很重要,因为更正确、更优雅的解决方案实际上不适用于此切割,而这与其他问题无关。有关更多详细信息,请参阅接受答案下方的我的评论。看起来与潜在副本中的答案相同…:p这里的问题是,当对任何jQuery对象调用val()
时,spy就会工作。因此,如果您稍后在html中更改用户名id,而不是在jQuery调用中更改用户名id,那么测试可能仍然会通过,而不应该通过。一个更正确/优雅的解决方案是另一个重复问题的解决方案。但是,这需要重构isValidEmail
,以便email
是一个函数参数,即使用依赖项注入。这很好,但是,b/c DI通常会使代码更加健壮、灵活,而且是的,可以测试。总结一个更好的解决方案:重构:函数isValidEmail($elmt){var email=$elmt.val();…}
。调用常规代码:isValidEmail($(“#用户名”)代码>。测试:it(“应该工作”,function(){var$elmt=$(“#username”);spyOn($elmt,“val”)…;var result=isValidEmail($elmt);…}
。注意:jQuery只调用一次,创建单个对象。更好的是,重构:function isValidEmailString(emailString){…
和function isValidEmail(){return isValidEmailString($(“#username”).val();
。然后测试isValidMailString
甚至不需要jQuery甚至DOM,只需要一个测试电子邮件字符串。
'use strict';
describe('test/spec/controllers/validation.js - No controller', function () {
describe('email validation', function () {
it('should be true for valid emails', function() {
spyOn($("#username"), "val").and.returnValue("test@test.com");
var result = isValidEmail();
expect(result).toEqual(true);
});
});
});
spyOn($.fn, 'val').and.returnValue('test@test.com')