SiNBLOG

140文字に入らないことを、極稀に書くBlog

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.