document.cookie
is like a string, but it is not a string. To quote the example from the Mozilla doc:
document.cookie = \"name=oeschger\";
docume
You could create an object with a cookie
setter and getter. Here is a very simple implementation:
var mock = {
value_: '',
get cookie() {
return this.value_;
},
set cookie(value) {
this.value_ += value + ';';
}
};
Might not work in all browsers though (especially IE). Update: It only works in browsers supporting 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
I know this is an old topic, but in my case expiring cookies was necessary so here's a solution that combines the above answers and a setTimeout
call to expire cookies after X
seconds:
const fakeCookies = {
// cookie jar
all: {},
// timeouts
timeout: {},
// get a cookie
get: function(name)
{
return this.all[ name ]
},
// set a cookie
set: function(name, value, expires_seconds)
{
this.all[ name ] = value;
if ( expires_seconds ) {
! this.timeout[ name ] || clearTimeout( this.timeout[ name ] )
this.timeout[ name ] = setTimeout(() => this.unset(name), parseFloat(expires_seconds) * 1000)
}
},
// delete a cookie
unset: function(name)
{
delete this.all[ name ]
}
}
This implementation allows overwriting cookies, and adds 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);
I figured out that jasmine has spyOnProperty
which can be used for when you want to spy on getter and setters of objects. So I solved my issue with this:
const cookie: string = 'my-cookie=cookievalue;';
spyOnProperty(document, 'cookie', 'get').and.returnValue(cookie);
@Felix Kling's answer is right on, I just wanted to point out that there is an alternate syntax for defining setters and getters 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"
And again, most browsers support ECMAScript 5 (defined by ECMA-262 5th Edition) but not MSIE (or JScript).
Personally i was unable to hijack the document object. A simple solution which seems to work for me was the following...
At the top of my test script i define a fakeCookie object:
var fakeCookie = {
cookies: [],
set: function (k, v) {
this.cookies[k] = v;
},
get: function (k) {
return this.cookies[k];
},
reset: function () {
this.cookies = [];
}
};
Then in my beforeEach() i define my cookie stub. This basically intercepts calls to jQuery.cookie and (instead!) call the callback function that i have defined (see below):
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]);
}
});
});
Any time that i get or set a cookie value it uses my fakeCookie instead of the real jQuery.cookie. It does this by looking at the number of parameters passed and deduces whether its a get/set. I literally pasted this in and it all worked straight off the bat. Hope this helps!!