2015-03-28 2 views
0

У меня есть 2 простых методы, абстрактные чтения и запись LocalStorage:Как мне модульное тестирование LocalStorage быть неопределенным с мокко/Sinon/Chai

_readLocalStorage: function(key) { 
    if (window.localStorage && window.localStorage.getItem(key)) { 
     return JSON.parse(window.localStorage.getItem(key)); 
    } else { 
     throw new Error('Could not read from localStorage'); 
    } 
}, 

_writeLocalStorage: function(key, data) { 
    try { 
     window.localStorage.setItem(key, JSON.stringify(data)); 
    } catch (e) { 
     throw new Error('Could not write to localStorage'); 
    } 
}, 

Очевидно, гася window.localStorage.getItem/SetItem прост. Но как насчет случая, когда localStorage не определен?

Я пробовал кэширование/отсоединение window.localStorage (второе утверждение):

describe('#_readLocalStorage', function() { 
    it('should read from localStorage', function() { 
     // set up 
     var stub1 = sinon.stub(window.localStorage, 'getItem') 
     .returns('{"foo": "bar"}'); 

     // run unit 
     var result = service._readLocalStorage('foo'); 

     // verify expectations 
     expect(result) 
     .to.eql({foo: 'bar'}); 

     // tear down 
     stub1.restore(); 
    }); 

    it('should throw an error if localStorage is undefined', function() { 
     // set up 
     var cachedLocalStorage = window.localStorage; 
     window.localStorage = undefined; 

     // run unit/verify expectations 
     expect(service._readLocalStorage('foo')) 
     .to.throw(new Error('Could not write to localStorage')); 

     // tear down 
     window.localStorage = cachedLocalStorage; 
    }); 
}); 

Это не работает, однако. Мокка/Чаи, похоже, не поймают заброшенную ошибку.

Я немного оглянулся, но не могу найти способ справиться с этим.

ответ

3

Ваш expect должен быть

expect(service._readLocalStorage.bind(service, 'foo')) 
    .to.throw(new Error('Could not write to localStorage')); 

Путь у вас есть ваш код вызывает service._readLocalStorage('foo')перед темexpect называется. Поэтому возникает исключение, которое не может обрабатывать expect. То, что expect должно иметь дело с исключениями, - это функция , которой будет звонить expectсам. Использование service._readLocalStorage.bind(service, 'foo') создает новую функцию, которая при вызове без аргументов (как и expect) будет эквивалентна вызову service._readLocalStorage('foo').

Есть еще одна проблема с вашим тестом: ваш код очистки никогда не будет выполнен. Библиотеки утверждений сообщают о проблемах, добавляя исключения JavaScript. Таким образом, любой код, который следует за неудачным исключением, не будет выполняться, если исключение специально не обрабатывается. Вы можете сделать:

it('should throw an error if localStorage is undefined', function() { 
    // set up 
    var cachedLocalStorage = window.localStorage; 
    window.localStorage = undefined; 

    // run unit/verify expectations 
    try { 
     expect(...)...; 
     expect(...)...; 
     ... 
    } 
    finally { 
     // tear down 
     window.localStorage = cachedLocalStorage; 
    } 
}); 

Для более сложных случаев следует использовать before, beforeEach, after, afterEach для установки и демонтажа.

+0

DERP, конечно, я не могу вызвать код очистки после исключения. Спасибо за ваш ответ, что отлично работает. –

Смежные вопросы