javascript - AngularJS 测试 - 注入(inject) -> 模块 -> 注入(inject)

标签 javascript angularjs unit-testing jasmine

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

  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,然后用它来创建我的mocks,用module注册我的mocks >,然后再次调用 inject 来抓取被测单元。

这导致

Error: Injector already created, can not register a module! in bower_components/angular-mocks/angular-mocks.js (line 2278)

我在这里看到很多关于 SO 的回答说你不能在 inject 之后调用 module,但是他们没有提供任何替代方案,比如以上。

这里正确的做法是什么?

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

最佳答案

module 用来定义哪些模块用inject加载,inject后不能调用,这是先有鸡还是先有蛋的情况。

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

If an object literal is passed each key-value pair will be registered on the module via $provide.value, the key being the string name (or token) to associate with the value on the injector.

createViewer 这样同时调用 moduleinject 的函数不能超过 1 个。如果这意味着这种自包含测试是一种反模式,那么对此无能为力。 Angular 测试最适合通常的习惯,包括 beforeEach 和局部变量。

为了消除对$q的依赖,mocked service可以做成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);
    }
  };
});

关于javascript - AngularJS 测试 - 注入(inject) -> 模块 -> 注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44388419/

相关文章:

javascript - Angular $scope 对象显示 $scope.data 但当我尝试使用它时,显示未定义

angular - 如何使用自己的依赖项测试内部嵌套组件的 Angular 2 组件? (TestBed.configureTestingModule)

javascript - 从二维数组中获取列

JavaScript HTML5 Canvas 碰撞检测

javascript - 在 HTML 中显示 Jquery Ajax 响应时出现问题

javascript - 如何将搜索结果附加到 div 标签,然后在下次搜索时覆盖内容?

angularjs - 从另一个 angular js Controller 更新一个 angular js Controller 的 ng-model

javascript - 如何将单个参数传递给自定义属性指令?

python - 如何用模拟模拟只读属性?

java - 如何为 Java 11 编译和运行我的 Maven 单元测试,同时为旧版本的 Java 8 编译我的代码