rad_nq
26 Mar 2007, 10:00 AM
For those trying to write unit tests on AJAX code:
The issue is when your callback is invoked the testXX() function has already been evaluated and returns. Putting assert statements inside of a callback only creates unhelpful exceptions that JSUnit does nothing with.
The solution is to convert all async calls to be synchronous calls.
The following bit of code we use in a simple "unitTestSupport.js" that is included on the unit test page so that the override is applied globally to all YAHOO.util.Connect.asyncRequest calls.
Note: If your success/failure methods are catching exceptions then you will have check the exceptions (eg. e.isJsUnitException) and throw the JSUnit generated ones so it can report correctly.
Lines of interest are "o.conn.open", the commented out "this.handleReadyState" and "if(callback)" block.
YAHOO.util.Connect.asyncRequest = function(method,uri,callback,postData){
var o=this.getConnectionObject();
if(!o){
return null;
}else{
if(this._isFormSubmit){
if(this._isFileUpload){
this.uploadFile(o.tId,callback,uri,postData);
this.releaseObject(o);
return;
}
if(method=='GET'){
if(this._sFormData.length!=0){
uri+=((uri.indexOf('?')==-1)?'?':'&')+this._sFormData;
}else{
uri+="?"+this._sFormData;
}
}else if(method=='POST'){
postData=postData?this._sFormData+"&"+postData:this._sFormData;
}
}
o.conn.open(method,uri, false);//Synchronous operation!.
if(this._isFormSubmit||(postData&&this._use_default_post_header)){
this.initHeader('Content-Type',this._default_post_header);
if(this._isFormSubmit){
this.resetFormState();
}
}
if(this._has_http_headers){
this.setHeader(o);
}
//this.handleReadyState(o,callback);
o.conn.send(postData||null);
//Send returns after all is complete. we must invoke callback ourselves.
if(callback){
var param = {status: o.conn.status, responseText: o.conn.responseText, argument: callback.argument};
if(o.conn.status == 200&& typeof callback.success == 'function'){
callback.success(param);
}else if(typeof callback.failure == 'function'){
callback.failure(param);
}
}
return o;
}
};
The issue is when your callback is invoked the testXX() function has already been evaluated and returns. Putting assert statements inside of a callback only creates unhelpful exceptions that JSUnit does nothing with.
The solution is to convert all async calls to be synchronous calls.
The following bit of code we use in a simple "unitTestSupport.js" that is included on the unit test page so that the override is applied globally to all YAHOO.util.Connect.asyncRequest calls.
Note: If your success/failure methods are catching exceptions then you will have check the exceptions (eg. e.isJsUnitException) and throw the JSUnit generated ones so it can report correctly.
Lines of interest are "o.conn.open", the commented out "this.handleReadyState" and "if(callback)" block.
YAHOO.util.Connect.asyncRequest = function(method,uri,callback,postData){
var o=this.getConnectionObject();
if(!o){
return null;
}else{
if(this._isFormSubmit){
if(this._isFileUpload){
this.uploadFile(o.tId,callback,uri,postData);
this.releaseObject(o);
return;
}
if(method=='GET'){
if(this._sFormData.length!=0){
uri+=((uri.indexOf('?')==-1)?'?':'&')+this._sFormData;
}else{
uri+="?"+this._sFormData;
}
}else if(method=='POST'){
postData=postData?this._sFormData+"&"+postData:this._sFormData;
}
}
o.conn.open(method,uri, false);//Synchronous operation!.
if(this._isFormSubmit||(postData&&this._use_default_post_header)){
this.initHeader('Content-Type',this._default_post_header);
if(this._isFormSubmit){
this.resetFormState();
}
}
if(this._has_http_headers){
this.setHeader(o);
}
//this.handleReadyState(o,callback);
o.conn.send(postData||null);
//Send returns after all is complete. we must invoke callback ourselves.
if(callback){
var param = {status: o.conn.status, responseText: o.conn.responseText, argument: callback.argument};
if(o.conn.status == 200&& typeof callback.success == 'function'){
callback.success(param);
}else if(typeof callback.failure == 'function'){
callback.failure(param);
}
}
return o;
}
};