Не получаю ответ от Mockjax с JsTestDriver - PullRequest
1 голос
/ 06 июля 2011

Я пытаюсь использовать mockjax, чтобы высмеивать мои вызовы jQuery Ajax; однако я не могу найти ни одного хорошего, рабочего примера того, как эффективно проверить ответы.

Следующий код представляет собой простую оболочку для объекта jQuery.Ajax. Это работает, но я хочу написать несколько тестов:

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));

У меня есть следующий тест JsTestDriver для getData.

Тестовый класс

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);
    }
});

Функция assertEquals должна возвращать false в этом примере , так как я ожидаю «success1», но во всем коде я пытаюсь установить значение «success». Я хочу, чтобы этот тест не прошел, поэтому я знаю, что он работает. Тем не менее, тест проходит успешно. Я пытался установить для функции successCallback значение results = "success", и оно все равно не "провалило" тест.

Как мне настроить этот тест, чтобы гарантировать, что ложный ответ будет возвращен, чтобы я не получил ложный положительный результат, который у меня есть в настоящее время?

1 Ответ

1 голос
/ 07 июля 2011

Я думаю, что проблема в том, что setTimeout заставляет тестовый набор завершаться без выполнения каких-либо утверждений, а assertEquals вызывается в отдельном «потоке».

Здесь вам нужен асинхронный тестовый пример:

(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);

Вы можете иметь столько вызовов очереди, сколько вы хотите в одном тесте, и все они будут выполняться только после завершения предыдущего. Вы можете прочитать больше об асинхронном тестовом примере в проекте JsTestDriver wiki . Надеюсь, это поможет!

О, почти забыл! Чтобы избежать случаев, когда у вас есть пройденный тест без утверждений, вы можете использовать функцию expectAsserts:

testcase.prototype.testSomeStuff = function(){
    expectAsserts(2);

    // Test your stuff here
};
...