2016-01-27 2 views
3

Как я могу протестировать завод, который использует $window.localStorage внутренне с помощью Jasmine и ngMock?Как выполнить модульное тестирование услуги AngularJS, которая использует localStorage внутренне

Вот что-то похожее на то, что у меня есть:

myApp.factory('myData',function ($window) { 
    return { 
     message: $window.localStorage['stuff'] 
    } 
}); 

Благодаря кучу!

ответ

6

следующие работы с жасмином 2.4:

angular.module('MyModule', []).factory('myData',function ($window) { 
    return { 
     message: function(){ 
      return $window.localStorage['stuff'] ; 
     } 
    } 
}); 

describe("TestName", function() { 
    beforeEach(module('MyModule')); 
    var myData, store; 
    beforeEach(inject(function(_myData_) { 
    myData = _myData_; 
    store = {}; 
    var localStorage = window.localStorage; 
    spyOn(localStorage, 'getItem').and.callFake(function (key) { 
     return store[key]; 
    }); 
    spyOn(localStorage, 'setItem').and.callFake(function (key, value) { 
     return store[key] = value + ''; 
    }); 
    spyOn(localStorage, 'clear').and.callFake(function() { 
     store = {}; 
    }); 
    })); 

    it("feature desc", function() { 
    localStorage['stuff'] = 'hello'; 
    expect(myData.message()).toEqual('hello'); 
    }); 
}); 

Примечание Использование _myData_ подчеркивания трюк (see docs).

+0

Отлично. Это сработало. Не знаю, почему, но я тоже пытался издеваться над фабрикой. – tanmay

0

Небольшое уточнение: в случае LocalStorage не содержит ключ этот фиктивный возврат undefined, но реальный возвращает null

(ключ) метод GetItem должен вернуть текущее значение, связанное с данным ключом. Если данный ключ не существует в списке, связанном с с объектом, тогда этот метод должен вернуть значение null. https://www.w3.org/TR/webstorage/

spyOn(localStorage, 'getItem').and.callFake(function (key) { 
    return store[key] !== undefined ? store[key] : null; 
    }); 

Примечание: В предыдущем примере метод removeItem был поругаем не

spyOn(localStorage, 'removeItem').and.callFake(function (key, value) { 
    delete store[key]; 
    }); 

P.S. Я нашел другой способ написать тесты с локальным хранилищем без макета, возможно, это имеет смысл, работа с примитивами и localStorage может быть сложной задачей.

afterEach(() => { 
    localStorage.removeItem(testTokenKey); 
}); 
Смежные вопросы