AngularJS测试 - 注入 - >模块 - >注入

时间:2017-06-06 11:10:15

标签: javascript angularjs unit-testing jasmine

我正在尝试测试依赖于其他服务documentViewer

的服务authService
  angular
    .module('someModule')
    .service('documentViewer', DocumentViewer);

  /* @ngInject */
  function DocumentViewer($q, authService) {
    // ...

    this.view = function(doc) {
      //...
    }
  }

这是我的测试目前的样子

it('test', inject(function($q) {
  var doc = {
    view: function() {
      return $q.resolve(0);
    }
  };

  var auth = {
    refreshProfileData: function() {
      return $q.resolve(0);
    },
  };

  var viewer = createViewer(auth);
}));

function createViewer(auth) {
  var viewer;

  module({
    authService: auth
  });
  inject(function(documentViewer) {
    viewer = documentViewer;
  });

  return viewer;
}

问题是,我需要致电inject来抓取$q,然后用它来创建我的模拟,使用module注册我的模拟,然后调用inject再次抓住被测单位。

这导致

  

错误:注射器已经创建,无法注册模块!在bower_components / angular-mocks / angular-mocks.js(第2278行)

我在这里看到了许多答案,说你不能在module之后拨打inject,但他们不提供上述场景的替代方案。

这里的正确方法是什么?

PS:我想避免使用beforeEach,我希望每个测试都是自包含的。

1 个答案:

答案 0 :(得分:2)

module用于定义将使用inject加载哪些模块,并且在inject之后无法调用,这是鸡蛋情况。

module接受的对象用于定义模拟服务with $provide.value

  

如果传递了一个对象文字,则每个键值对将通过$ provide.value在模块上注册,该键是与注入器上的值关联的字符串名称(或标记)。

createViewer调用moduleinject的函数不能超过1个。如果这意味着这种自包含的测试是反模式,那么就没有什么可以做的。角度测试最适合通常的习惯,包括beforeEach和局部变量。

为了消除对$q的依赖,可以将模拟服务设为factory

it('test', function () {
  var authFactory = function ($q) {
    return {
      refreshProfileData: function() {
        return $q.resolve(0);
      },
    };
  };

  // mocks defined first
  module(function ($provide) {
    $provide.factory('authService': authFactory);
  });

  var viewer;
  inject(function(documentViewer) {
    viewer = documentViewer;
  });
  // no module(...) is allowed after this point

  var $q;
  inject(function(_$q_) {
    $q = _$q_;
  });

  var doc = {
    view: function() {
      return $q.resolve(0);
    }
  };
});