【问题标题】:How to mock cookies with QUnit and Sinon?如何用 QUnit 和 Sinon 模拟 cookie?
【发布时间】:2017-10-08 21:44:48
【问题描述】:

我有这个代码:

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

我需要模拟/存根 document.cookie,但我对 Sinon 和 QUnit 完全陌生。
谁能给我解释一下我做错了什么?

提前致谢!
斯尔詹

【问题讨论】:

  • 根据你的测试结果,通过了就没有问题了:) 你到底想知道什么?如何从存根返回响应?请具体。
  • 我不想调用 document.cookie 因为这是特定于浏览器的。
  • 所以我必须找到一种方法来存根文档属性。

标签: javascript sinon qunit


【解决方案1】:

实际上你不能用 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);

【讨论】:

    猜你喜欢
    • 2013-05-09
    • 2013-08-15
    • 2021-01-07
    • 1970-01-01
    • 2012-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-22
    相关资源
    最近更新 更多