如何在角度单元测试中模拟服务的依赖关系?

时间:2016-04-11 22:02:59

标签: angularjs unit-testing karma-runner karma-mocha

我正在使用业力,角度和摩卡。

我要注入的MyServices模块。它的addThing方法也会调用$localStorage提供程序,我想测试$localStorage.setItem

时隐式调用MyServices.addThing(data)方法

这是我的代码:

describe('MyServices', function() {
  var $q;
  var $rootScope;
  var $scope;
  var MyServices;
  var $timeout;
  var $httpBackend;

  // inject modules
  beforeEach(function(){
    module('my.stuff');

    var _LocalStorage_ = {
      setItem: function(){
        return 'foo';
      }
    };

    // mock the dependencies of the module we are testing
    module(function ($provide) {
      $provide.value('$localStorage', _LocalStorage_); //here is where the error occurs
    });
  });

  beforeEach(inject(function (_$q_, _$rootScope_, _$timeout_, _MyServices_, _$httpBackend_) {
    $q = _$q_;
    $rootScope = _$rootScope_;
    $timeout = _$timeout_;
    MyServices = _MyServices_;
    $httpBackend = _$httpBackend_;
    $scope = $rootScope.$new();
  }));

  it.only('should call a method and access localStorage', function(){
    var spyAdd = sinon.spy(MyServices, 'addThing');
    var spySetItem = sinon.spy($localStorage, 'setItem');

    MyServices.addThing({ name: 'Thing' });

    expect(spyAdd.callCount).to.equal(1);
    expect(spySetItem.callCount).to.equal(1);
  })
});

当我运行它时,我收到$localStorage未定义的错误。

2 个答案:

答案 0 :(得分:0)

你没有注册假$ localStorage,只需使用原来的并在setItem方法上创建一个间谍。

所以删除此

var _LocalStorage_ = {
  setItem: function(){
    return 'foo';
  }
};
module(function ($provide) {
  $provide.value('$localStorage', _LocalStorage_); //here is where the error occurs
});

但是在这里注入

var $localStorage;
beforeEach(inject(function (_$q_, _$rootScope_, _$timeout_, _MyServices_, _$httpBackend_, _$localStorage_) {
  $q = _$q_;
  $rootScope = _$rootScope_;
  $timeout = _$timeout_;
  MyServices = _MyServices_;
  $httpBackend = _$httpBackend_;
  $scope = $rootScope.$new();
  $localStorage = _$localStorage_; //here
}));

因为你已经在方法上创建了一个间谍,所以在测试中不需要改变任何东西。

答案 1 :(得分:0)

尝试在beforeEach之外声明 LocalStorage 。顺便说一句,你不需要_,你可以称之为LocalStorage。

我还建议下载SinonJS,因为它在监视或模拟依赖项时有很多有用的方法。