如何在内部对使用localStorage的AngularJS服务进行单元测试

时间:2016-01-27 09:41:26

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

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

这与我的相似:

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

非常感谢!

2 个答案:

答案 0 :(得分:6)

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

答案 1 :(得分: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];
  });

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

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