AJAX呼び出しを行うJavaScriptのQUnitテストをいくつか書いています。
分離のために、_$.ajax
_を上書きして、変数へのAJAX呼び出しのパラメーター配列を書き込みます。これは、メソッドがAJAX関数を使用する方法をテストするために、しかし、私は $.load()
の成功ハンドラをテストするのが難しい
http://api.jquery.com/load/ のドキュメントから:
成功した応答が検出された場合(つまり、textStatusが「success」または「notmodified」の場合)、. load()は一致した要素のHTMLコンテンツを返されたデータに設定します。
そのため、成功ハンドラーの変数と同じ名前のオブジェクトを含むオブジェクトを返そうとしました。
_ //Mock ajax function
$.ajax = function (param) {
_mockAjaxOptions = param;
var fakeAjaxSuccess = { responseText: "success", textStatus: "success", XMLHttpRequest: "success" };
return fakeAjaxSuccess;
};
_
しかし、このアプローチはうまくいきませんでした。
成功したAJAX呼び出しの動作を再現するにはどうすればよいですか?
@Robustoと@Valに触発された読書の後、私は動作する方法を見つけました:
_//Mock ajax function
$.ajax = function (param) {
_mockAjaxOptions = param;
//call success handler
param.complete("data", "textStatus", "jqXHR");
};
_
実際の$ .ajaxコードからイベントを発生させたり、イベントをトリガーしたりする代わりに、偽のajaxオブジェクトに、関数($.ajax()
へのパラメーターとして渡される)を偽の関数の一部として呼び出させます。
この質問には数年かかり、jQueryの新しいバージョンでは少し変更されています。
ジャスミンでこれを行うには、 マイケルファラガのアプローチ を試すことができます
ソリューション
function ajax_response(response) {
var deferred = $.Deferred().resolve(response);
return deferred.promise();
}
ジャスミン使用
describe("Test test", function() {
beforeEach(function() {
spyOn($, 'ajax').and.returnValue(
ajax_response([1, 2, 3])
);
});
it("is it [1, 2, 3]", function() {
var response;
$.ajax('GET', 'some/url/i/fancy').done(function(data) {
response = data;
});
expect(response).toEqual([1, 2, 3]);
});
});
ジャスミンなし
$.ajax = ajax_response([1, 2, 3]);
$.ajax('GET', 'some/url/i/fancy').done(function(data) {
console.log(data); // [1, 2, 3]
});
$.ajax
をオーバーライドします受け入れられた答え と ser1634074によって投稿された答え を試した後、この2つの単純で柔軟なブレンドを考案しました。
最も基本的な形で…
function ajax_response(response) {
return function (params) {
params.success(response);
};
}
$.ajax = ajax_response('{ "title": "My dummy JSON" }');
上記の例では、引数としてJSON文字列(または応答のシミュレーションに役立つ任意の数のカスタム引数)を受け取り、$.ajax
に割り当てられる匿名のクロージャー関数を返す関数ajax_response()
を定義します単体テストのオーバーライド。
無名関数は、$.ajax
関数に渡される設定オブジェクトを含むparams
引数を受け入れます。そして、外部関数に渡された引数を使用して、サーバーからの応答をシミュレートします。この例では、success
コールバックを呼び出してダミーのJSONを提供するだけで、サーバーからの正常な応答を常にシミュレートします。
簡単に再構成できます…
function ajax_response(response, success) {
return function (params) {
if (success) {
params.success(response);
} else {
params.error(response);
}
};
}
// Simulate success
$.ajax = ajax_response('{ "title": "My dummy JSON." }', true);
doAsyncThing(); // Function that calls $.ajax
// Simulate error
$.ajax = ajax_response('{ "error": "Who is the dummy now?" }', false);
doAsyncThing(); // Function that calls $.ajax
以下で実際にそれを見ることができます…
/* FUNCTION THAT MAKES AJAX REQUEST */
function doAsyncThing() {
$.ajax({
type: "POST",
url: "somefile.php",
// data: {…},
success: function (results) {
var json = $.parseJSON(results),
html = $('#ids').html();
$('#ids').html(html + '<br />' + json.id);
}
});
}
/* BEGIN MOCK TEST */
// CREATE CLOSURE TO RETURN DUMMY FUNCTION AND FAKE RESPONSE
function ajax_response(response) {
return function (params) {
params.success(response);
};
}
var n = Prompt("Number of AJAX calls to make", 10);
for (var i = 1; i <= n; ++i) {
// OVERRIDE $.ajax WITH DUMMY FUNCTION AND FAKE RESPONSE
$.ajax = ajax_response('{ "id": ' + i + ' }');
doAsyncThing();
}
/* END MOCK TEST */
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="ids">IDs:</p>
ここでの答えは良いものですが、バックエンドサービスが構築されるまで他のすべてのAPI呼び出しを同じままにして、UIで何かを構築し続けることができるように、単一のAPI呼び出しに対する偽の応答を構築する必要がありました。
APIオブジェクトは内部で$ .ajaxを使用するため、次のようなAPIメソッドを呼び出すことができます。
api.products({ price: { $lt: 150, tags: ['nike', 'shoes'] } })
.done(function(json) {
// do something with the data
})
.error(function(err) {
// handle error
});
このメソッドはトリックを行います:
function mockAjax(options) {
var that = {
done: function done(callback) {
if (options.success)
setTimeout(callback, options.timeout, options.response);
return that;
},
error: function error(callback) {
if (!options.success)
setTimeout(callback, options.timeout, options.response);
return that;
}
};
return that;
}
次に、$。ajaxに触れずに単一のAPI呼び出しをオーバーライドします。
api.products = function() {
return mockAjax({
success: true,
timeout: 500,
response: {
results: [
{ upc: '123123', name: 'Jordans' },
{ upc: '4345345', name: 'Wind Walkers' }
]
}
});
};
下のリンクが役立つと思います。パラメータに関しては、私はそれほど確信していませんが、そうかもしれません。
$.fn.ajax.success = function (){
///the rest goest here
}
JQueryのドキュメントを見てください:Ajaxセットアップは、テストされる他の多くの条件を提供することがわかります。それらをすべてあなたのfakeAjaxSuccessに向けると、目的を達成できる可能性があります。
または、$.ajax
独自の関数を呼び出し、fakeAjaxSuccess
オブジェクトを使用してイベントハンドラーを呼び出すだけです。