How to mock localStorage in JavaScript unit tests?

前端 未结 14 1555
南笙
南笙 2020-11-29 18:46

Are there any libraries out there to mock localStorage?

I\'ve been using Sinon.JS for most of my other javascript mocking and have found it is really gr

相关标签:
14条回答
  • 2020-11-29 19:35

    just mock the global localStorage / sessionStorage (they have the same API) for your needs.
    For example:

     // Storage Mock
      function storageMock() {
        let storage = {};
    
        return {
          setItem: function(key, value) {
            storage[key] = value || '';
          },
          getItem: function(key) {
            return key in storage ? storage[key] : null;
          },
          removeItem: function(key) {
            delete storage[key];
          },
          get length() {
            return Object.keys(storage).length;
          },
          key: function(i) {
            const keys = Object.keys(storage);
            return keys[i] || null;
          }
        };
      }
    

    And then what you actually do, is something like that:

    // mock the localStorage
    window.localStorage = storageMock();
    // mock the sessionStorage
    window.sessionStorage = storageMock();
    
    0 讨论(0)
  • 2020-11-29 19:35

    Overwriting the localStorage property of the global window object as suggested in some of the answers won't work in most JS engines, because they declare the localStorage data property as not writable and not configurable.

    However I found out that at least with PhantomJS's (version 1.9.8) WebKit version you could use the legacy API __defineGetter__ to control what happens if localStorage is accessed. Still it would be interesting if this works in other browsers as well.

    var tmpStorage = window.localStorage;
    
    // replace local storage
    window.__defineGetter__('localStorage', function () {
        throw new Error("localStorage not available");
        // you could also return some other object here as a mock
    });
    
    // do your tests here    
    
    // restore old getter to actual local storage
    window.__defineGetter__('localStorage',
                            function () { return tmpStorage });
    

    The benefit of this approach is that you would not have to modify the code you're about to test.

    0 讨论(0)
提交回复
热议问题