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.
source to share
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);
}
};
});
source to share