2011-06-23 14 views
17

document.cookie è come una stringa, ma non è una stringa. Per citare l'esempio dalla Mozilla doc:È possibile simulare document.cookie in JavaScript?

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

Se si è tentato di fare un cookie finta utilizzando solo una stringa, si non ottenere gli stessi risultati:

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

Quindi, se si voleva per testare un modulo che funziona sul cookie, e se volessi usare un simulato cookie per quei test, potresti? Come?

+0

getter e setter in browser Web più recenti. – zzzzBov

+0

Puoi provare un semplice oggetto fittizio che ho scritto a questo scopo: https://github.com/RichardKnop/CookieMock –

risposta

14

È possibile creare un oggetto con un setter e un getter cookie. Ecco un'implementazione molto semplice:

var mock = { 
    value_: '', 

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

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

Tuttavia non funziona in tutti i browser (specialmente IE). Aggiornamento: Funziona solo nei browser che supportano 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

Quindi, quello che intendi è che puoi, ovviamente, imitare il comportamento, ma l'interfaccia _cannot_ essere la stessa . È giusto? – thisgeek

+0

@thisgeek: Non sei sicuro di cosa intendi ... è la stessa interfaccia o mi manca qualcosa? –

+0

Ho letto male ciò che hai scritto.Non c'era ':' tra 'get' e' cookie', ma la mia mente la mise lì comunque. Ciò significa che la tua soluzione dipende dal supporto di ECMAScript 5 nel motore JS, con cui posso convivere. – thisgeek

8
risposta

@Felix Re è proprio su, volevo solo far notare che v'è una sintassi alternativa per la definizione setter e getter in 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" 

E ancora , la maggior parte dei browser supporta ECMAScript 5 (definito da ECMA-262 5th Edition) ma non MSIE (o JScript).

6

Questa implementazione consente di sovrascrivere i cookie, e aggiunge 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

Unire deve essere eseguito con un separatore ";" per seguire l'implementazione effettiva: 'return output.join ("; ");' – Alvis

0

Personalmente non sono riuscito a dirottare l'oggetto del documento. Una soluzione semplice che sembra funzionare per me è stato il seguente ...

Nella parte superiore del mio script di test ho definire un oggetto fakeCookie:

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

Poi nel mio beforeeach() definisco il mio biscotto stub. (! Invece) Questo intercetta fondamentalmente chiamate a jQuery.cookie e chiamare la funzione di callback che ho definito (vedi sotto):

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]); 
     } 
    }); 
}); 

Ogni volta che ottengo o impostare un valore di cookie che usa il mio fakeCookie al posto del vero jQuery.cookie. Lo fa guardando il numero di parametri passati e deduce se è un get/set. Ho letteralmente incollato questo e tutto ha funzionato subito. Spero che questo aiuti !!

Problemi correlati