在Jest测试中,我一直得到“localStorage is not defined”,这是有意义的,但我的选项是什么?碰壁。


当前回答

一个更好的替代方法,它处理未定义的值(它不需要toString()),如果值不存在则返回null。用react v15、redux和redux-auth-wrapper进行了测试

class LocalStorageMock {
  constructor() {
    this.store = {}
  }

  clear() {
    this.store = {}
  }

  getItem(key) {
    return this.store[key] || null
  }

  setItem(key, value) {
    this.store[key] = value
  }

  removeItem(key) {
    delete this.store[key]
  }
}

global.localStorage = new LocalStorageMock

其他回答

要在Typescript中做同样的事情,请执行以下步骤:

设置一个包含以下内容的文件:

let localStorageMock = (function() {
  let store = new Map()
  return {

    getItem(key: string):string {
      return store.get(key);
    },

    setItem: function(key: string, value: string) {
      store.set(key, value);
    },

    clear: function() {
      store = new Map();
    },

    removeItem: function(key: string) {
        store.delete(key)
    }
  };
})();
Object.defineProperty(window, 'localStorage', { value: localStorageMock });

然后将以下行添加到包中。json在你的Jest配置

:“setupTestFrameworkScriptFile PATH_TO_YOUR_FILE”,

或者在您想要模拟本地存储的测试用例中导入该文件。

首先,我创建了一个名为localStorage.ts(localStorage.js)的文件

class LocalStorageMock {
  store: Store;
  length: number;

  constructor() {
    this.store = {};
    this.length = 0;
  }

  key(n: number): any {
    if (typeof n === 'undefined') {
      throw new Error(
        "Uncaught TypeError: Failed to execute 'key' on 'Storage': 1 argument required, but only 0 present."
      );
    }

    if (n >= Object.keys(this.store).length) {
      return null;
    }

    return Object.keys(this.store)[n];
  }

  getItem(key: string): Store | null {
    if (!Object.keys(this.store).includes(key)) {
      return null;
    }

    return this.store[key];
  }

  setItem(key: string, value: any): undefined {
    if (typeof key === 'undefined' && typeof value === 'undefined') {
      throw new Error(
        "Uncaught TypeError: Failed to execute 'setItem' on 'Storage': 2 arguments required, but only 0 present."
      );
    }

    if (typeof value === 'undefined') {
      throw new Error(
        "Uncaught TypeError: Failed to execute 'setItem' on 'Storage': 2 arguments required, but only 1 present."
      );
    }

    if (!key) return undefined;

    this.store[key] = value.toString() || '';
    this.length = Object.keys(this.store).length;

    return undefined;
  }

  removeItem(key: string): undefined {
    if (typeof key === 'undefined') {
      throw new Error(
        "Uncaught TypeError: Failed to execute 'removeItem' on 'Storage': 1 argument required, but only 0 present."
      );
    }

    delete this.store[key];
    this.length = Object.keys(this.store).length;
    return undefined;
  }

  clear(): undefined {
    this.store = {};
    this.length = 0;

    return undefined;
  }
}

export const getLocalStorageMock = (): any => {
  return new LocalStorageMock();
};

global.localStorage = new LocalStorageMock();

然后创建名为session.test.ts的测试文件(session.test.js)

import { getLocalStorageMock } from '../localstorage';
describe('session storage', () => {
  let localStorage;
  beforeEach(() => {
    localStorage = getLocalStorageMock();
  });

  describe('getItem', () => {
    it('should return null if the item is undefined', () => {
      expect(localStorage.getItem('item')).toBeNull();
    });
    it("should return '' instead of null", () => {
      localStorage.setItem('item', '');
      expect(localStorage.getItem('item')).toBe('');
    });
    it('should return navid', () => {
      localStorage.setItem('item', 'navid');
      expect(localStorage.getItem('item')).toBe('navid');
    });

  });
});

这对我很有效,

delete global.localStorage;
global.localStorage = {
getItem: () => 
 }

我从github找到了这个解决方案

var localStorageMock = (function() {
  var store = {};

  return {
    getItem: function(key) {
        return store[key] || null;
    },
    setItem: function(key, value) {
        store[key] = value.toString();
    },
    clear: function() {
        store = {};
    }
  }; 
})();

Object.defineProperty(window, 'localStorage', {
 value: localStorageMock
});

您可以在setupTests中插入这段代码,它应该可以正常工作。

我在一个使用typesctipt的项目中测试了它。

在我的例子中,我需要在检查localStorage值之前设置它。

我所做的就是

const data = { .......}

const setLocalStorageValue = (name: string, value: any) => {
  localStorage.setItem(name, JSON.stringify(value))
}



 describe('Check X class', () => {
  setLocalStorageValue('Xname', data)
  const xClass= new XClass()

  console.log(xClass.initiate()) ; // it will work 

  
})