如何用 QUnit 和 Sinon 模拟 cookie?
How to mock cookies with QUnit and Sinon?
我有这个代码:
var CookieHelper = function () {
return {
GetCookie : function (cookieName) {
var cookieNameRequest = cookieName + "=";
var cookiesCollection = document.cookie.split(";");
for (var i = 0; i < cookiesCollection.length; i++) {
var cookieValuePair = cookiesCollection[i];
while (cookieValuePair.charAt(0) == " ") cookieValuePair = cookieValuePair.substring(1, cookieValuePair.length);
if (cookieValuePair.indexOf(cookieNameRequest) == 0)
return cookieValuePair.substring(cookieNameRequest.length, cookieValuePair.length);
}
return null;
},
DeleteCookie : function (cookieName) {
CookieHelper.SetCookie(cookieName, "", -1);
},
SetCookie : function (cookieName, cookieValue, cookieExpirationDays) {
var tmpDate = new Date;
if (cookieExpirationDays) {
tmpDate.setTime(tmpDate.getTime() + cookieExpirationDays * 24 * 60 * 60 * 1000);
var expires = "; expires=" + tmpDate.toGMTString();
} else {
// if cookieExpirationDays isn't set cookie will expire at the end of the day
var expirationTime = new Date(tmpDate.getFullYear(), tmpDate.getMonth(), tmpDate.getDate(), 23, 59, 59);
var expires = "; expires=" + expirationTime.toGMTString();
}
document.cookie = cookieName + "=" + cookieValue + expires + "; path=/;" + (location.protocol === "https:" ? "secure=true" : "");
}
};
}();
我需要为 GetCookie 编写单元测试。
我试过:
QUnit.module('Cookie Helper Tests');
QUnit.test('GetCookie - returns no cookie', function(assert) {
var stub = sinon.spy(CookieHelper, 'GetCookie');
var cookieName = 'testCookieName';
var cookieValue = CookieHelper.GetCookie(cookieName);
assert.ok(cookieValue == null, 'returns no cookie');
});
我需要 mock/stub document.cookie 但我对 Sinon 和 QUnit 完全陌生。
谁能给我解释一下我做错了什么?
提前致谢!
Srdjan
实际上你不能用 Sinon 模拟属性,而且你不能模拟 document.cookies 属性 因为它是不可变的。但是,您可以做的是使用模仿原始对象行为的假双对象,如 here.
所述
例如,如果您 运行 在浏览器之外(例如在 NodeJS 中)进行相同的测试,您会做类似的事情
const chai = require('chai');
const sinon = require('sinon');
const SinonChai = require('sinon-chai');
chai.use(SinonChai);
chai.should();
context('test', function() {
it('should pass',
(done) => {
var cookieName = 'testCookieName';
document = {
cookie: cookieName + '=123'
};
var cookieValue = CookieHelper.GetCookie(cookieName);
console.log(cookieValue);
done();
});
});
为了将 document 对象引入上下文并通过返回固定结果来模仿它的 cookies 属性。
现在,浏览器有一个解决方法,包括重新定义 'document.cookie' 的 getter 和 setter,如 here:
所述
(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);
我有这个代码:
var CookieHelper = function () {
return {
GetCookie : function (cookieName) {
var cookieNameRequest = cookieName + "=";
var cookiesCollection = document.cookie.split(";");
for (var i = 0; i < cookiesCollection.length; i++) {
var cookieValuePair = cookiesCollection[i];
while (cookieValuePair.charAt(0) == " ") cookieValuePair = cookieValuePair.substring(1, cookieValuePair.length);
if (cookieValuePair.indexOf(cookieNameRequest) == 0)
return cookieValuePair.substring(cookieNameRequest.length, cookieValuePair.length);
}
return null;
},
DeleteCookie : function (cookieName) {
CookieHelper.SetCookie(cookieName, "", -1);
},
SetCookie : function (cookieName, cookieValue, cookieExpirationDays) {
var tmpDate = new Date;
if (cookieExpirationDays) {
tmpDate.setTime(tmpDate.getTime() + cookieExpirationDays * 24 * 60 * 60 * 1000);
var expires = "; expires=" + tmpDate.toGMTString();
} else {
// if cookieExpirationDays isn't set cookie will expire at the end of the day
var expirationTime = new Date(tmpDate.getFullYear(), tmpDate.getMonth(), tmpDate.getDate(), 23, 59, 59);
var expires = "; expires=" + expirationTime.toGMTString();
}
document.cookie = cookieName + "=" + cookieValue + expires + "; path=/;" + (location.protocol === "https:" ? "secure=true" : "");
}
};
}();
我需要为 GetCookie 编写单元测试。
我试过:
QUnit.module('Cookie Helper Tests');
QUnit.test('GetCookie - returns no cookie', function(assert) {
var stub = sinon.spy(CookieHelper, 'GetCookie');
var cookieName = 'testCookieName';
var cookieValue = CookieHelper.GetCookie(cookieName);
assert.ok(cookieValue == null, 'returns no cookie');
});
我需要 mock/stub document.cookie 但我对 Sinon 和 QUnit 完全陌生。
谁能给我解释一下我做错了什么?
提前致谢!
Srdjan
实际上你不能用 Sinon 模拟属性,而且你不能模拟 document.cookies 属性 因为它是不可变的。但是,您可以做的是使用模仿原始对象行为的假双对象,如 here.
所述例如,如果您 运行 在浏览器之外(例如在 NodeJS 中)进行相同的测试,您会做类似的事情
const chai = require('chai');
const sinon = require('sinon');
const SinonChai = require('sinon-chai');
chai.use(SinonChai);
chai.should();
context('test', function() {
it('should pass',
(done) => {
var cookieName = 'testCookieName';
document = {
cookie: cookieName + '=123'
};
var cookieValue = CookieHelper.GetCookie(cookieName);
console.log(cookieValue);
done();
});
});
为了将 document 对象引入上下文并通过返回固定结果来模仿它的 cookies 属性。
现在,浏览器有一个解决方法,包括重新定义 'document.cookie' 的 getter 和 setter,如 here:
所述(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);