2011-06-23 11 views
17

document.cookieは文字列のようですが、文字列ではありません。 Mozilla docから例を引用すると:document.cookieをJavaScriptでモックすることは可能ですか?

document.cookie = "name=oeschger"; 
document.cookie = "favorite_food=tripe"; 
alert(document.cookie); 
// displays: name=oeschger;favorite_food=tripe 

あなたは文字列のみを使用してモッククッキーを作ってみました場合は、ないは、同じ結果を得るでしょう:

var mockCookie = ""; 
mockCookie = "name=oeschger"; 
mockCookie = "favorite_food=tripe"; 
alert(mockCookie); 
// displays: favorite_food=tripe 

だから、あなたが望むならばクッキーで動作するモジュールを単体テストすること、そしてそれらのテストにモッククッキーを使用したいのであれば、あなたはできますか? どのようにですか?

+0

最近のWebブラウザではゲッターとセッター。 – zzzzBov

+0

私はこの目的のために書いたシンプルなモックオブジェクトを試すことができます:https://github.com/RichardKnop/CookieMock –

答えて

14

cookieセッターとゲッターを使用してオブジェクトを作成できます。ここには非常に単純な実装があります:

var mock = { 
    value_: '', 

    get cookie() { 
     return this.value_; 
    }, 

    set cookie(value) { 
     this.value_ += value + ';'; 
    } 
}; 

ただし、(特にIE)のすべてのブラウザで動作するとは限りません。 更新: ECMAScript 5をサポートするブラウザでのみ動作します!

More about getter and setters

mock.cookie = "name=oeschger"; 
mock.cookie = "favorite_food=tripe"; 
alert(mock.cookie); 
// displays: name=oeschger;favorite_food=tripe; 

DEMO

+0

それで、あなたはもちろん、その動作を模倣することができますが、インターフェイスは同じではないことを暗示しています。そうですか? – thisgeek

+0

@thisgeek:あなたが何を意味するのかわからない...それは同じインターフェースですか、何か不足していますか? –

+0

あなたが書いたものを誤解しました。'get'と' cookie'の間に ':'はありませんでしたが、私の心はとにかくそれを置いています。つまり、あなたのソリューションはJSエンジンのECMAScript 5サポートに依存しています。 – thisgeek

8

@Felix王の答えは、私はちょうどのECMAScript 5でセッターとゲッターを定義するための代替構文があることを指摘したかった、右側にある:

function MockCookie() { 
    this.str = ''; 
    this.__defineGetter__('cookie', function() { 
    return this.str; 
    }); 
    this.__defineSetter__('cookie', function(s) { 
    this.str += (this.str ? ';' : '') + s; 
    return this.str; 
    }); 
} 
var mock = new MockCookie(); 
mock.cookie = 'name=oeschger'; 
mock.cookie = 'favorite_food=tripe'; 
mock.cookie; // => "name=oeschger;favorite_food=tripe" 

そして再びほとんどのブラウザはECMAScript 5(ECMA-262 5th Editionで定義)をサポートしますが、ではなく、 MSIE(またはJScript)をサポートしています。

6

この実装では、クッキーを上書きすることができます、と私は、ドキュメントオブジェクトをハイジャックすることができませんでしたdocument.clearCookies()個人的に

(function (document) { 
    var cookies = {}; 
    document.__defineGetter__('cookie', function() { 
     var output = []; 
     for (var cookieName in cookies) { 
      output.push(cookieName + "=" + cookies[cookieName]); 
     } 
     return output.join(";"); 
    }); 
    document.__defineSetter__('cookie', function (s) { 
     var indexOfSeparator = s.indexOf("="); 
     var key = s.substr(0, indexOfSeparator); 
     var value = s.substring(indexOfSeparator + 1); 
     cookies[key] = value; 
     return key + "=" + value; 
    }); 
    document.clearCookies = function() { 
     cookies = {}; 
    }; 
})(document); 
+0

実際の実装に従うには、 ";"区切りで結合する必要があります: 'return output.join("; ");' – Alvis

0

を追加します。 私のために働くように見えるシンプルなソリューション従っていました...

私のテストスクリプトの先頭で私はfakeCookieオブジェクト定義:私は私のクッキーを定義します)(私のbeforeEachに続いて

var fakeCookie = { 
    cookies: [], 
    set: function (k, v) { 
     this.cookies[k] = v; 
    }, 
    get: function (k) { 
     return this.cookies[k]; 
    }, 
    reset: function() { 
     this.cookies = []; 
    } 
}; 

をスタブ。これは、(下記参照)は、基本的にjQuery.cookieへの呼び出しをインターセプトし、(代わりに!)私が定義したコールバック関数を呼び出します。

beforeEach(function() { 
    var cookieStub = sinon.stub(jQuery, "cookie", function() { 
     if (arguments.length > 1) { 
      fakeCookie.set(arguments[0], arguments[1]); 
     } 
     else { 
      return fakeCookie.get(arguments[0]); 
     } 
    }); 
}); 

私が手やクッキーの値を設定し、任意の時間が、それは代わりに私のfakeCookieを使用しています本当のjQuery.cookie。これは、渡されたパラメータの数を調べることによって行い、その取得/設定を推測します。私は文字通りこれを貼り付け、それはすべてバットから直ちに働いた。 これが役立つことを願っています!

関連する問題