make javascript function callback-ish
我正在使用jquery的javascript函数:
my.namespace.loadSomeStuff = function() { $.get('/Services/loadStuff', function(c){ $("#stuffDiv").html(c); }); };
我正在尝试为此编写unit testing。
现在,因为这个函数并没有真正返回任何东西并使用jquery的’get’异步加载一些东西我很难测试它。
基本上我想做的是调用这个函数,等到它返回一些东西,然后访问加载的元素来validation…类似于:
my.namespace.loadSomeStuff(function(){ alert('boo'); assertSame('Login', $("#stuffDiv").find(......); });
现在,我在调用unit testing的模板中创建了一个,它将正确加载和显示,但警报或断言永远不会执行。
我有没有办法在不增加大量额外代码的情况下实现这一目标?
谢谢
你必须在loadSomeStuff
方法中添加一个参数来接收你在示例代码中调用的回调函数,然后故意调用它:
my.namespace.loadSomeStuff= function(callback) { $.get('/Services/loadStuff', function(c){ $("#stuffDiv").html(c); if (callback!==undefined) callback(); }); };
我不确定仅仅为了支持unit testing而使代码更复杂是值得的,尽管你可能会认为向异步函数添加回调是通用的有用性。
另一种方法是使测试使用粗略的超时。
您可以使用Nick提到的ajaxSuccess
(可能结合超时和/或捕获ajaxError
?)。 但令我印象深刻的是,这可能会增加一些unit testing的实施知识。 如果loadSomeStuff
将来在没有XMLHttpRequest的情况下更改,或者有时仅在没有缓存时使用它,该怎么办? 然后unit testing就会中断。 当然,你可以更新测试以匹配实现,但那不是真正有用的unit testing,是吗?
您可以使用全局AJAX事件 ,例如:
$(document).ajaxSuccess(function() { assertSame('Login', $("#stuffDiv").find(......)); });
ajaxSuccess
将在每个 AJAX请求之后发生,如果你想在所有同步请求完成后运行一个事件,那么ajaxStop
就是你所追求的。 这两个处理程序不必直接附加到您的AJAX方法 ,它们可以在unit testing中完成。
这些是正常事件( 此处为完整列表 ),因此您可以根据需要使用.bind()
/ .unbind()
,例如,当完成上述unit testing时:
$(document).ajaxSuccess(function() { assertSame('Login', $("#stuffDiv").find(......)); $(this).unbind('ajaxSuccess'); //cleanup });