goog.net.XhrIoを使ってみた!
Closure LibraryでXMLHttpRequestを扱う。goog.net.XhrIoを使ってみました。
app.js
xhrioSample.App.prototype.getBookList = function(xhrio){
//取得成功
gevents.listen(xhrio, goog.net.EventType.SUCCESS, function(e){
var res = e.target.getResponseJson('while(1);');
var bookList = gdom.getElement('book-list');
var data = {
bookList: []
};
for (var i = 0, len = e['bookList'].length; i < len; i++) {
data.bookList[i] = {
isbn: e['bookList'][i]['isbn'],
name: e['bookList'][i]['name'],
link: e['bookList'][i]['link']
};
}
gdom.append(bookList, gsoy.renderAsElement(templates.book.bookList, data));
});
//取得失敗
gevents.listen(xhrio, goog.net.EventType.ERROR, function(e){
console.log('ERROR');
console.log(e);
});
//レスポンスが返ってきた
gevents.listen(xhrio, goog.net.EventType.COMPLETE, function(e){
console.log('COMPLETE');
var bookList = gdom.getElement('book-list');
gdom.removeChildren(bookList);
});
var bookList = gdom.getElement('book-list');
xhrio.send('/closurelibrary/xhriosample/list');
}
直接関係ない部分を省略していますが、こんな感じです。
Server側からjsonでデータを受け取って、表示しています。
Error処理なんか手抜きですが、上記のような感じでイベントをハンドリングできます。
公式のサンプルを見ると、上記以外にも幾つかのハンドリング可能なイベントがありますね。
Asynchronous XMLHttpRequests with XhrIo | Closure Library | Google Developers
後、これのUnitTestも頑張って書いてみました。
test.html
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>XhrIO Sample Test</title> <script src="/closure-library/closure/goog/base.js"> </script> <script> goog.require('goog.testing.jsunit'); goog.require('goog.testing.TestQueue'); goog.require('goog.testing.net.XhrIo'); </script> <script src="deps.js"> </script> </head> <body> <div id="main"> <button id="view-book-list-button" class="goog-custom-button"> view book list </button> <div id="book-list"> </div> </div> <script> goog.require('xhrioSample.App'); </script> <script> function testXhrIoSuccess(){ var queue = new goog.testing.TestQueue(); var xhrio = new goog.testing.net.XhrIo(queue); xhrioSample.App.getInstance().getBookList(xhrio); assertFalse('リクエストが発行されなかった', queue.isEmpty()); var req = queue.dequeue(); assertEquals('URLが不正', req[1], '/closurelibrary/xhriosample/list'); xhrio.simulateResponse(200, '{"status":"OK","bookList":[{"key":{"kind":"Book","id":0,"name":"9999999999999"},"version":1,"isbn":"9999999999999","name":"Test Book Name!!"}]}', {}); var main = goog.dom.getElement('main'); var isbn = goog.dom.getElementByClass("isbn", main); var isbnText = goog.dom.getTextContent(isbn); assertNotNullNorUndefined('ISBN表示失敗', isbnText); assertEquals('ISBN表示失敗', '9999999999999', isbnText); var name = goog.dom.getElementByClass("name", main); var nameText = goog.dom.getTextContent(name); assertNotNullNorUndefined('書籍名表示失敗', nameText); assertEquals('書籍名表示失敗', 'Test Book Name!!', nameText); var amazon = goog.dom.getElementByClass("amazon", main); var amazonText = goog.dom.getTextContent(amazon); assertNotNullNorUndefined('AmazonLink表示失敗', amazonText); assertEquals('AmazonLink表示失敗', 'amazon', amazonText); } function testXhrIoError(){ var queue = new goog.testing.TestQueue(); var xhrio = new goog.testing.net.XhrIo(queue); xhrioSample.App.getInstance().getBookList(xhrio); assertFalse('リクエストが発行されなかった', queue.isEmpty()); var req = queue.dequeue(); assertEquals('URLが不正', req[1], '/closurelibrary/xhriosample/list'); xhrio.simulateResponse(404, '', {}); var bookList = goog.dom.getElement('book-list'); var bookListText = goog.dom.getTextContent(bookList); assertEquals('Error表示', 'Error', bookListText); } </script> </body> </html>
見本となるようなコードなのかは自信はないですが・・・。
goog.net.XhrIoをテストするためには、以下の2つを利用しています。
goog.testing.TestQueue
goog.testing.net.XhrIo
この2つを利用することで、実際にServerを起動させること無く、Serverのレスポンスをシミュレートさせています。
本当は、getBookList()の引数にXhrIoを渡すのではなく、getBookList()の中でXhrIoを作成し、テスト時にはgoog.net.XhrIoコンストラクタをモックにすることで、テストを行いたかったのですが、モックへの置き換え方法がよく分からず、とりあえずここまでで断念・・・。
最後に今回のソースはこちら!
app.js
Google Code Archive - Long-term storage for Google Code Project Hosting.
test.html
Google Code Archive - Long-term storage for Google Code Project Hosting.