tddjs > Ajax p262 スタブにようる実装2

XMLHttpRequestをスタブを使いテスト getメソッドをスタブで実装 sendメソッドをスタブで実装

by s_hiroshi

HTML

<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css">
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
  <h1 id="qunit-header">QUnit example</h1>  <h2 id="qunit-banner"></h2>  <div id="qunit-testrunner-toolbar"></div>  <h2 id="qunit-userAgent"></h2>  <ol id="qunit-tests"></ol>  <div id="qunit-fixture">test markup, will be hidden</div>

JavaScript

// テストダブルの例

// スタブ
// フェイクオブジェクト

// スタブはあらかじめプログラミングされた振る舞いを持つテストダブルである。
// スタブは、引数がなんであっても同じ値を返したり、例外を投げたりする。
// スタブは実際のオブジェクト、関数の代わりに使われるので、テストに不要な
// テストに不要なインターフェースを使わずに済ませる方法としても使われる。
// 1. ajax.createメソッドにスタブfnを設定する
// 2. ajax.createメソッドの戻り値XMLHttpRequestは
// fakeXMLHttpRequestをフェイクオブジェクトとして使う。
// 3. fakeXMLHttpRequestはopenメソッドのみ実行。


// コンストラクタを使わないでオブジェクトからオブジェクトを生成する
if (!Object.create) {
    (function() {
        function F() {}
        Object.create = function(object) {
            F.prototype = object;
            return new F();
        };
    }());
}


// 名前空間
var tddjs = {};
tddjs.namespace = function() {
    var object = this;
    return function(name) {
        if (typeof object[name] == "undefined") {
            object[name] = {};
        }
        return object[name];
    };
}();


// スタブ
// クロージャー
// fnが実行されると実行済みフラグや実引数を設定し、returnValueを返す

function stubFn(returnValue) {
    var fn = function() {
        fn.called = true;
        fn.args = arguments;
        return returnValue;
    };

    fn.called = false;

    return fn;
}


// XMLXttpRequestのフェイク
var fakeXMLHttpRequest = {
    // open -> send
    open: stubFn(),
    send: stubFn(),
};

(function() {
    var xhr;
    var ajax = tddjs.namespace("ajax");

    // XMLhttpRequestの候補
    var options = [
        function() {
        return new ActiveXObject("Microsoft.XMLHTTP");},
        function() {
        return new XMLHttpRequest();}];

    // ajax.createメソッドを機能検出してクロスブラウザ対応検査
    // option[i]()でXMLHttpRequestを正常に生成できたらajax.createに設定
    var i, l;
    for (i = 0, l = options.length; i < l; i++) {
        try {
            xhr = options[i]();
            ajax.create = options[i];
            break;
        } catch (e) {}
    }


    // 公開用メソッド
    function _get(url) {
        if (typeof url != "string") {
            throw new TypeError('URL should be string');
        }
        var transport = ajax.create();
        transport.open("GET", url, true);
        transport.send();
       ...