2012-03-29 7 views
0

Ich versuche, ein sehr einfaches jQuery-Plugin zu testen, das einfach $ .ajax-Methode aufruft und seinen Inhalt in ein Element legt. Zum Testen verwende ich JsTestDriver und Sinon zum Mocking.jQuery Ajax-Test funktioniert nicht

Plugin-Datei sieht:

(function($) { 
    $.fn.transfer = function() { 

    $.ajax({ 
     url : 'friends', 
    type : 'GET', 
    contentType : 'application/json', 
    dataType : 'json', 
    success : function(html) { 
     console.log("-"+html+"-"); 
     console.log($(this)); 
     $(this).html(html); 
     console.log("+"+$(this).html()+"+") 
    } 
}); 
}; 
})(jQuery); 

In der Theorie sehr einfaches Plugin.

Und dann habe ich einen Komponententest spöttischen Erfolgsfunktion geschrieben:

TestCase("Ajax ", { 
    'test response' : function() { 
     /*:DOC divElement = <div id="container" style="height: 100px;"></div>*/ 
     sinon.stub(jQuery, "ajax").yieldsTo(
      "success", 'alex'); 
     $(this.divElement).transfer(); 
     console.log("*"+$(this.divElement).text()+"*"); 
    } 
}); 

es scheint zu korrigieren. Wenn Sie dann diesen Test ausführen, werden die nächsten Zeilen über die Konsole gedruckt:

So erfolgreich Funktion empfängt "Alex" Zeichenfolge korrekt. Dann wird $ (this) reference ausgedruckt, die Nachricht wird mit der Funktion html() gesetzt, und wenn ich den vorherigen gesetzten Wert protokolliere, wird eine Null zurückgegeben. Und die letzte Protokollnachricht befindet sich in der Testdatei, wo Sie sehen können, dass AJAX-Text nicht gesetzt ist.

Weiß jemand, was ich falsch mache? Weil ich sicher bin, dass mir etwas fehlt, das ich jetzt nicht sehen kann.

+0

console.log ($ (this)); bezieht sich auf das Ajax-Objekt - nicht das Element an das Plugin übergeben – mikevoermans

+0

Sie json dataType mit Strings im Test mischen, schwer zu folgen, was Sie wollen – charlietfl

Antwort

0

Verwendung Synchron AJAX

JS Testfahrer und die meisten Test-Frameworks ich kenne haben ein bisschen ein Problem asynchrones Javascript, was im Grunde die unzusammenhängende Art von asynchronen Aufrufen Schrauben, die Reihenfolge der Testausführung bis (man denke: Test 2 startet, bevor Test 1 beendet ist). Aus diesem Grund versuchen Sie synchornische Ajax-Aufrufe für die Dauer Ihrer Tests, indem Sie die globale Async-Eigenschaft mit jQuery.ajaxSetup() festlegen.

// Use synchronous AJAX 
jQuery.ajaxSetup({async: false}); 

TestCase("Ajax ", { 
    'test1' : function() { 
     // etc... 
    } 
}); 

// Revert to default 
jQuery.ajaxSetup({async: true}); 
+0

Ich stimme nicht zu. js-test-driver unterstützt das Testen asynchroner Funktionen. Es ist nicht das, was ich einfach nenne, aber es ist möglich und verständlich. Soweit ich es verstehe, hatte der Thread-Besitzer keine Probleme mit mehreren Testfällen, die nicht synchron waren, sondern einen Testfall für eine Methode schreiben, die asynchrones Verhalten verwendet. – Friederike

0

Ich empfehle Ihnen, die AsyncTestCase verwenden, die von js-Test-Treiber zur Verfügung gestellt wird. Es behandelt asynchrone Prozesse gut.

Fügen Sie Ihre verspotteten Server-Methode den Callbacks in der Warteschlange hinzu, so dass der Test wartet, bis der "Server" aufgerufen wurde. Etwas wie folgt aus:

var AjaxTest = AsyncTestCase('AjaxTest'); 

AjaxTest.prototype.testResponse = function(queue) { 
    /*:DOC divElement = <div id="container" style="height: 100px;"></div>*/ 

    queue.call('Set up mocked server', function(callbacks) {   
     var serverStub = sinon.stub(jQuery, "ajax").yieldsTo("success", 'alex'); 
     callbacks.add(serverStub); 

     $(this.divElement).transfer(); 
    }); 

    queue.call('Make assertions here', function() { 
     console.log("*"+$(this.divElement).text()+"*"); 
    }); 
}; 

Hinweis: Ich habe den Code nicht versucht. Hoffe, es gibt keine Tippfehler. ;)