首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在JavaScript单元测试中模拟localStorage?

如何在JavaScript单元测试中模拟localStorage?
EN

Stack Overflow用户
提问于 2012-07-15 00:24:46
回答 17查看 100.6K关注 0票数 121

有没有可以模拟localStorage的库?

我一直在使用Sinon.JS来模拟我的其他javascript,我发现它真的很棒。

我最初的测试显示,localStorage拒绝在火狐(sadface)中赋值,所以我可能需要一些破解:/

到目前为止(如我所见),我的选择如下:

  1. 创建我的所有代码都使用的包装函数,并模拟那些为localStorage.
  2. ??????

创建某种(可能很复杂)状态管理(测试前的快照,在清理恢复快照中)的

  • localStorage

你对这些方法有什么看法,你认为还有其他更好的方法吗?无论哪种方式,我都会将最终生成的“库”放在github上,以实现开源的好处。

EN

回答 17

Stack Overflow用户

发布于 2013-01-17 23:04:19

这里有一个用Jasmine模拟它的简单方法:

let localStore;

beforeEach(() => {
  localStore = {};

  spyOn(window.localStorage, 'getItem').and.callFake((key) =>
    key in localStore ? localStore[key] : null
  );
  spyOn(window.localStorage, 'setItem').and.callFake(
    (key, value) => (localStore[key] = value + '')
  );
  spyOn(window.localStorage, 'clear').and.callFake(() => (localStore = {}));
});

如果您想在所有测试中模拟本地存储,请在测试的全局范围内声明上面所示的beforeEach()函数(通常的位置是specHelper.js脚本)。

票数 145
EN

Stack Overflow用户

发布于 2014-10-03 19:07:37

只需模拟全局localStorage / sessionStorage (它们具有相同的接口)即可满足您的需求。

例如:

 // 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;
      }
    };
  }

然后你实际要做的事情是这样的:

// mock the localStorage
window.localStorage = storageMock();
// mock the sessionStorage
window.sessionStorage = storageMock();
票数 56
EN

Stack Overflow用户

发布于 2013-11-23 04:04:38

还要考虑在对象的构造函数中注入依赖项的选项。

var SomeObject(storage) {
  this.storge = storage || window.localStorage;
  // ...
}

SomeObject.prototype.doSomeStorageRelatedStuff = function() {
  var myValue = this.storage.getItem('myKey');
  // ...
}

// In src
var myObj = new SomeObject();

// In test
var myObj = new SomeObject(mockStorage)

为了与模拟和单元测试保持一致,我喜欢避免测试存储实现。例如,检查设置项目后存储长度是否增加没有意义,等等。

由于替换实际localStorage对象上的方法显然是不可靠的,因此请使用“哑巴”mockStorage并根据需要将各个方法存根,例如:

var mockStorage = {
  setItem: function() {},
  removeItem: function() {},
  key: function() {},
  getItem: function() {},
  removeItem: function() {},
  length: 0
};

// Then in test that needs to know if and how setItem was called
sinon.stub(mockStorage, 'setItem');
var myObj = new SomeObject(mockStorage);

myObj.doSomeStorageRelatedStuff();
expect(mockStorage.setItem).toHaveBeenCalledWith('myKey');
票数 23
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11485420

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档