2011-06-23 25 views
17

document.cookie giống như một chuỗi, nhưng nó không phải là một chuỗi. Để trích dẫn ví dụ từ Mozilla doc:Có thể giả lập document.cookie bằng JavaScript không?

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

Nếu bạn đã cố gắng để làm cho một cookie giả chỉ sử dụng một chuỗi, bạn sẽ không có được kết quả tương tự:

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

Vì vậy, nếu bạn muốn để kiểm tra đơn vị một mô-đun hoạt động trên cookie và nếu bạn muốn sử dụng cookie giả cho các thử nghiệm đó, bạn có thể? Làm cách nào?

+0

getters & setters trong các trình duyệt web gần đây hơn. – zzzzBov

+0

Bạn có thể thử một đối tượng giả đơn giản mà tôi đã viết cho mục đích này: https://github.com/RichardKnop/CookieMock –

Trả lời

14

Bạn có thể tạo một đối tượng với trình cài đặt và khởi động cookie. Dưới đây là triển khai rất đơn giản:

var mock = { 
    value_: '', 

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

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

Có thể không hoạt động trên tất cả các trình duyệt (đặc biệt là IE). Cập nhật: Nó chỉ hoạt động trong các trình duyệt hỗ trợ 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

Vì vậy, những gì bạn ngụ ý là bạn có thể, tất nhiên, bắt chước hành vi, nhưng giao diện _cannot_ giống nhau . Có đúng không? – thisgeek

+0

@thisgeek: Không chắc chắn ý bạn là gì ... đó là giao diện tương tự hoặc tôi thiếu gì đó? –

+0

Tôi đã đọc sai những gì bạn đã viết.Không có ':' giữa 'get' và' cookie', nhưng tâm trí của tôi đặt nó ở đó. Điều đó có nghĩa là giải pháp của bạn phụ thuộc vào hỗ trợ ECMAScript 5 trong công cụ JS mà tôi có thể sử dụng. – thisgeek

8

@Felix King câu trả lời như vậy là hợp trên, tôi chỉ muốn chỉ ra rằng có một cú pháp thay thế để xác định setters và thu khí trong 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" 

Và một lần nữa , hầu hết các trình duyệt đều hỗ trợ ECMAScript 5 (được xác định bởi ECMA-262 5th Edition) nhưng không phải MSIE (hoặc JScript).

6

thực hiện Điều này cho phép ghi đè lên tập tin cookie, và cho biết thêm 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

Tham gia phải được thực hiện bằng dấu phân tách ";" để thực hiện theo thực hiện thực tế: 'return output.join ("; ");' – Alvis

0

Cá nhân tôi đã không thể chiếm quyền điều khiển đối tượng tài liệu. Một giải pháp đơn giản mà dường như làm việc đối với tôi là như sau ...

Ở phía trên cùng của kịch bản thử nghiệm của tôi, tôi xác định một đối tượng fakeCookie:

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

Sau đó, trong beforeEach của tôi() i xác định cookie của tôi sơ khai. (! Thay) này về cơ bản chặn cuộc gọi đến jQuery.cookie và gọi hàm callback mà tôi đã xác định (xem dưới đây):

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

Bất cứ lúc nào mà tôi có được, hoặc thiết lập một giá trị cookie nó sử dụng fakeCookie tôi, thay cho jQuery.cookie thực sự. Nó thực hiện điều này bằng cách xem xét số lượng các tham số được truyền và suy ra cho dù đó là một get/set. Tôi thực sự đã dán nó vào và tất cả đều hoạt động ngay lập tức. Hy vọng điều này sẽ giúp !!

Các vấn đề liên quan