【问题标题】:How to unit-test an AngularJS service that uses localStorage internally如何对内部使用 localStorage 的 AngularJS 服务进行单元测试
【发布时间】:2016-05-04 04:30:47
【问题描述】:

如何使用 Jasmine 和 ngMock 对内部使用 $window.localStorage 的工厂进行单元测试?

这与我所拥有的类似:

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

非常感谢!

【问题讨论】:

    标签: javascript angularjs unit-testing jasmine local-storage


    【解决方案1】:

    以下适用于 Jasmine 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)。

    【讨论】:

    • 太棒了。这行得通。不知道为什么,但我也试图嘲笑工厂。
    【解决方案2】:

    小说明:如果 localStorage 不包含密钥,此模拟返回 undefined,但真实返回 null

    getItem(key) 方法必须返回与关联的当前值 给定的键。如果给定的键在关联的列表中不存在 对于对象,则此方法必须返回 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];
      });
    

    附:我找到了另一种使用本地存储编写测试而不模拟它的方法,这可能是有道理的,使用原语和 localStorage 可能会很棘手。

    afterEach(() => {
      localStorage.removeItem(testTokenKey);
    });
    

    【讨论】:

    • 本地存储在测试之间持续存在。删除本地存储密钥是防止一个测试对另一个测试产生副作用的好方法。
    猜你喜欢
    • 1970-01-01
    • 2016-12-21
    • 2019-04-12
    • 1970-01-01
    • 2012-11-19
    • 2016-05-21
    • 1970-01-01
    • 2012-06-01
    相关资源
    最近更新 更多