Angle Tests - Injection & # 8594; module & # 8594; injection

I am trying to test a service documentViewer

that depends on some other serviceauthService

  angular
    .module('someModule')
    .service('documentViewer', DocumentViewer);

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

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

      

This is what my test looks like at the moment

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;
}

      

The problem is that I need to call inject

to capture $q

and then use it to create my mocks, register my mocks with module

and then call again inject

to capture the device under test.

The result is

Error: the injector has already been created, the module cannot be registered! in bower_components / angular-mocks / angular-mocks.js (line 2278)

I have seen many answers here saying that you cannot call module

after inject

, but they do not offer an alternative to a scenario like the one above.

What's the correct approach here?

PS: I would like to avoid using it beforeEach

, I want every test to be self-contained.

+3


source to share


1 answer


module

is used to determine which modules will be loaded with inject

and cannot be called after inject

, this is the chicken egg situation.

The object accepted module

is used to define the mocked services with$provide.value

:

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



There can be no more than 1 type function here createViewer

that calls both module

and inject

. If it means that such a self-sufficient test is an anti-pattern, there is nothing to be done about it. Angular testing works best with common habits, including beforeEach

local variables.

To eliminate dependence on $q

, a mocked service can be made 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);
    }
  };
});

      

+2


source







All Articles