I'm attempting to use mockjax to mock my jQuery Ajax calls; however, I am not able to find any good, working examples of how to effectively test the responses.
The following code is a simple wrapper for the jQuery.Ajax object. It works but I want to write some tests around such:
Ajax Wrapper
if (!namespace){
var namespace = {};
}
namespace.Ajax = (function($){
function defaultError(xhr, err, msg){
if (typeof console !== 'undefined'){
var log = console.error;
if (!log) {
log = console.log;
}
log("==========================================");
log("An error occurred with the request.");
log("- Status Code: " + xhr.status);
log("- Status Text: " + xhr.statusText);
log("- Response Text: " + xhr.responseText);
log("- Message: " + msg);
log("=========================开发者_高级运维=================");
}
}
function getData(url, data, successCallback, errorCallback){
if (!errorCallback){
errorCallback = defaultError;
}
$.ajax({
url: url
, data: data
, success: successCallback
, error: errorCallback
});
}
function postData(url, data, successCallback, errorCallback){
if (!errorCallback){
errorCallback = defaultLog;
}
$.ajax({
type: "POST"
, url: url
, data: data
, success: successCallback
, error: errorCallback
});
}
return {
getData : getData
, postData: postData
}
}(jQuery));
I have the following JsTestDriver test for the getData.
Test Class
TestCase("Ajax Object Test Fixture", {
"test Calling getData Should Return content" : function(){
var results;
var obj = namespace.Ajax;
$.mockjax({
url: "/test"
, responseTime: 1
, responseText: "success"
});
obj.getData("/test"
, null
, function(data){results = data; });
setTimeout(function(){assertEquals("'success' Should be Returned.", "success1", results);}, 500);
}
});
The assertEquals function should return false in this example since I'm expecting "success1" but throughout the code I try to set the value to "success". I want this test to fail so I know it's working. As it is though, the test succeeds. I have event tried to set the successCallback function to just be results = "success"
and it still doesn't "fail" the test.
How do I set up this test to ensure the mock response is returned so I am not getting the false positive that I have currently?
I think the problem here is that setTimeout causes the testcase to quit without running any assertions, and the assertEquals gets called in a separate "thread".
What you need here is an asynchronous testcase:
(function(namespace){
var testcase = AsyncTestCase('AjaxObjectTest');
/**
* Each asynchronous testcase method receives a queue object.
*/
testcase.prototype.testGetData = function(queue) {
var results;
var obj = namespace.Ajax;
$.mockjax({
url: "/test",
responseTime: 1,
responseText: "success"});
// Here we pass a function to the queue call method, which will
// pause the testcase execution until all callback methods have been
// called, or until it expires.
queue.call('Expecting a callback', function(callbacks){
// The callbacks object is a factory for creating required
// callback functions. This queued function will wait until it
// has been called. You can specify the number of times you require
// it to be called as the second parameter of the add method.
var handler = callbacks.add(function(data){
assertEquals("'success' Should be Returned.", "success1", data);
});
obj.getData("/test", null, handler);
}
});
})(namespace);
You can have as many queue calls as you want in a single test, and all of them will be run only after the previous one finishes. You can read more about the asynchronous testcase in the JsTestDriver project wiki. Hope that helps!
Oh, almost forgot! To avoid cases where you have a passed test with no assertions, you can use the expectAsserts
function:
testcase.prototype.testSomeStuff = function(){
expectAsserts(2);
// Test your stuff here
};
精彩评论