Как провести модульное тестирование localStorage с помощью sinon

Я пытаюсь проверить localStorage с помощью sinon. По сути, я очень новичок в модульном тестировании, поэтому это может быть очень просто.

Обновить

Мне удалось придумать это, но теперь это дает мне новую ошибку Should wrap property of object

Тест

describe('Initial State', () => {
    it('should set the initial state for the component', () => {
const props = {
        currentUser: {}
      };
      sinon.stub(window.localStorage, 'setItem');
      window.localStorage.setItem('none', 'nothing');
    });
  });

person Umair Sarfraz    schedule 15.08.2016    source источник
comment
@anoop Я прошел через это. Ранее я тестировал объект location с той же процедурой, и он работал нормально. Однако в данном случае это дает мне Attempted to wrap undefined property setItem as function   -  person Umair Sarfraz    schedule 15.08.2016
comment
@DmitriyNevzorov Согласен, не надо. Но если я не проверю это, все остальные тесты не пройдут и выдадут ошибку, что localStorage не определено.   -  person Umair Sarfraz    schedule 15.08.2016


Ответы (2)


Мне удалось это решить. Спасибо @anoop, потому что его ответ помог, но мне пришлось справиться с этим с помощью основного обходного пути. Я использую jsdom, и в настоящее время он НЕ поддерживает localStorage. Я добавил подделку в свою конфигурацию jsdom.

if (!global.window.localStorage) {
  global.window.localStorage = {
    getItem() { return '{}'; },
    setItem() {}
  };
}

И утверждал это с помощью:

it('should fetch from local storage', () => {
      const props = {
        currentUser: 'UMAIR',
        user: {
          is_key: false
        }
      };

      const spy = sinon.spy(global.window.localStorage, "setItem");
      spy(props);
      expect(spy.calledWith( {
        currentUser: 'UMAIR',
        user: {
          is_key: false
        }
      }));
      spy.restore();

      const stub = sinon.stub(global.window.localStorage, 'getItem');
      stub(props);
      expect(stub.calledWith(Object.keys(props)));
// stub.restore();
    });

Также см.: Как имитировать localStorage в модульных тестах JavaScript?

https://github.com/gor181/webpack-react-babel-mocha-boilerplate/tree/master/test/utils

Я также обнаружил внутреннюю проблему в Sinon неделю назад, связанную с этим, но она была решена.

См.: https://github.com/sinonjs/sinon/issues/1129.

Надеюсь, это поможет кому-то.

person Umair Sarfraz    schedule 16.08.2016

Вы можете использовать babel-plugin-rewire, чтобы заменить localStorage фиктивной версией во всех ваших тестах.

Вот как я его использую:

import {unauth, signOut, __RewireAPI__} from 'modules/auth/actions';

const rewrite = __RewireAPI__.__Rewire__;

const local = {}; // object where you store all values localStorage needs to return
const storage = {
  get(key) {
    return local[key];
  },
  set: sinon.spy(),
  remove: sinon.spy()
};

rewrite('storage', storage); // rewrite storage package with your mocked version

// in you test add values you want to get from localStorage
local.credentials = constants.CREDENTIALS;
local.authToken = constants.TOKEN;
person Dmitriy Nevzorov    schedule 15.08.2016
comment
Я видел и другие пакеты, чтобы издеваться над localStore. Это может быть правильно, но то, чего я пытаюсь добиться, - это издеваться над ним вручную с помощью глобального объекта. Что-то вроде global.window = { localStorage: {.. - person Umair Sarfraz; 15.08.2016