【问题标题】:how do I mock a dependency of a service in my angular unit test?如何在我的角度单元测试中模拟服务的依赖关系?
【发布时间】:2016-08-02 06:55:13
【问题描述】:

我正在使用业力、角度和摩卡咖啡。

我要注入的MyServices 模块。它是addThing 方法也调用了$localStorage 提供程序,我想测试当我调用MyServices.addThing(data)$localStorage.setItem 方法已被隐式调用

这是我的代码:

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 未定义。

【问题讨论】:

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


    【解决方案1】:

    你没有注册那个伪造的 $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
    }));
    

    由于您已经在该方法上创建了一个 spy,因此在测试中无需更改任何内容。

    【讨论】:

    • 它不能用于注入,因为它与 MyServices 注入位于不同的命名空间中。如果我加载命名空间,我将不得不模拟 100 件事情。所以我想用$provide.value('$localStorage', myMock)来伪造它的存在@
    • 不同的命名空间是什么意思,就像在不同的模块中一样?无论如何,只需尝试 $provide.factory 而不是 $provide.value。
    • 我试过 $provide.factory 它说它不是 $get 函数。
    • 如果你使用 .factory,第二个参数应该是一个函数而不是一个对象。 $provide.factory('$localStorage', function(){return LocalStorage;});
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-08
      • 2019-12-14
      • 1970-01-01
      • 2015-02-04
      • 1970-01-01
      • 1970-01-01
      • 2017-08-07
      • 1970-01-01
      相关资源
      最近更新 更多