115

Jasmineを使用して、基本的なjQueryAJAXリクエストのBDD仕様を記述しようとしています。私は現在、スタンドアロンモード(つまりからSpecRunner.html)でJasmineを使用しています。jqueryおよびその他の.jsファイルをロードするようにSpecRunnerを構成しました。以下が機能しない理由はありますか?「yuppi!」と思っても、has_returnedはtrueになりません。アラートは正常に表示されます。

describe("A jQuery ajax request should be able to fetch...", function() {

  it("an XML file from the filesystem", function() {
    $.ajax_get_xml_request = { has_returned : false };  
    // initiating the AJAX request
    $.ajax({ type: "GET", url: "addressbook_files/addressbookxml.xml", dataType: "xml",
             success: function(xml) { alert("yuppi!"); $.ajax_get_xml_request.has_returned = true; } }); 
    // waiting for has_returned to become true (timeout: 3s)
    waitsFor(function() { $.ajax_get_xml_request.has_returned; }, "the JQuery AJAX GET to return", 3000);
    // TODO: other tests might check size of XML file, whether it is valid XML
    expect($.ajax_get_xml_request.has_returned).toEqual(true);
  }); 

});

コールバックが呼び出されたことをテストするにはどうすればよいですか?Jasmineを使用した非同期jQueryのテストに関連するブログ/資料へのポインタは大歓迎です。

4

6 に答える 6

235

実行できるテストには2つのタイプがあると思います。

  1. (Jasmine のスパイを使用して) AJAX リクエストを偽装する単体テスト。これにより、AJAX リクエストの直前と直後に実行されるすべてのコードをテストできます。Jasmine を使用して、サーバーからの応答を偽造することもできます。実際の AJAX が実行されていないため、これらのテストは高速になり、非同期動作を処理する必要がなくなります。
  2. 実際の AJAX リクエストを実行する統合テスト。これらは非同期である必要があります。

ジャスミンは、両方の種類のテストを行うのに役立ちます。

以下は、AJAX リクエストを偽造し、ユニット テストを記述して、偽造された AJAX リクエストが正しい URL に送信されることを確認する方法のサンプルです。

it("should make an AJAX request to the correct URL", function() {
    spyOn($, "ajax");
    getProduct(123);
    expect($.ajax.mostRecentCall.args[0]["url"]).toEqual("/products/123");
});

function getProduct(id) {
    $.ajax({
        type: "GET",
        url: "/products/" + id,
        contentType: "application/json; charset=utf-8",
        dataType: "json"
    });
}

代わりにJasmine 2.0を使用する場合:

expect($.ajax.calls.mostRecent().args[0]["url"]).toEqual("/products/123");

この回答で述べたように

以下は、AJAX リクエストが正常に完了したときに、コールバックが実行されたことを確認する同様の単体テストです。

it("should execute the callback function on success", function () {
    spyOn($, "ajax").andCallFake(function(options) {
        options.success();
    });
    var callback = jasmine.createSpy();
    getProduct(123, callback);
    expect(callback).toHaveBeenCalled();
});

function getProduct(id, callback) {
    $.ajax({
        type: "GET",
        url: "/products/" + id,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: callback
    });
}

代わりにJasmine 2.0を使用する場合:

spyOn($, "ajax").and.callFake(function(options) {

この回答で述べたように

最後に、統合の目的で、実際の AJAX 要求を行う統合テストを作成する必要があるかもしれないことを別の場所でほのめかしました。これは Jasmine の非同期機能 (waits()、waitsFor()、runs()) を使用して実行できます。

it("should make a real AJAX request", function () {
    var callback = jasmine.createSpy();
    getProduct(123, callback);
    waitsFor(function() {
        return callback.callCount > 0;
    });
    runs(function() {
        expect(callback).toHaveBeenCalled();
    });
});

function getProduct(id, callback) {
    $.ajax({
        type: "GET",
        url: "data.json",
        contentType: "application/json; charset=utf-8"
        dataType: "json",
        success: callback
    });
}
于 2011-06-01T09:37:51.657 に答える
13

jasmine-ajax プロジェクトを見てください: http://github.com/pivotal/jasmine-ajax

これは、(jQuery または Prototype.js のいずれかの場合に) XHR レイヤーでスタブするドロップイン ヘルパーであり、リクエストが送信されないようにします。その後、要求について必要なすべてを期待できます。

次に、すべてのケースに対してフィクスチャ応答を提供し、必要な各応答 (成功、失敗、無許可など) のテストを作成できます。

非同期テストの領域から Ajax 呼び出しを取り除き、実際の応答ハンドラーがどのように動作するかをテストするための柔軟性を提供します。

于 2011-01-12T17:00:00.600 に答える
5

Jasmine で ajax コードを指定するときは、リモート呼び出しを開始する依存関数 ($.get や $ajax など) をスパイして問題を解決します。次に、それに設定されたコールバックを取得し、個別にテストします。

これは私が最近要点を挙げた例です:

https://gist.github.com/946704

于 2011-05-22T00:51:54.567 に答える
0

jqueryspy.com を試す これは、テストを記述するためのエレガントな jquery のような構文を提供し、ajax が完了した後にコールバックをテストできるようにします。統合テストに最適で、最大 ajax 待機時間を秒またはミリ秒で構成できます。

于 2012-07-24T16:22:25.377 に答える