Lorsque l’unité teste une Angular factory (avec Karma + Jasmine), comment puis-je injecter une dépendance de stub dans l’usine testée?
Voici mon usine:
mod = angular.module('myFactoryMod', []);
mod.factory('myFactory', [
'$log', 'oneOfMyOtherServices', function($log, svc) {
return makeSomethingThatDoesSomethingWithTheseDependencies($log, svc);
}
]);
oneOfMyOtherServices
est nécessaire pour instancier mon usine.
Voici mon test:
it('can get an instance of my factory', function() {
var oneOfMyOtherServicesStub;
angular.mock.module('myFactoryMod');
oneOfMyOtherServicesStub = {
someVariable: 1
};
//****How do I get my stub in my target? ****
angular.mock.inject(['myFactory', function(target) {
expect(target).toBeDefined();
}
]);
})
N.B. Je le sais $controller
permet cela pour les contrôleurs, mais je ne vois pas d'équivalent pour les usines.
À ma connaissance, il existe deux manières d'accomplir quelque chose comme cela:
$provide
et un module anonyme pour injecter la maquette.La deuxième option ne fonctionne que si vous savez exactement quelles méthodes votre code testé va appeler sur le service injecté et vous pouvez facilement les imiter. Comme vous semblez accéder à une propriété de données sur le service (plutôt qu’à une méthode), il peut être préférable de choisir la première option.
En utilisant $provide
ressemblerait à peu près à ceci:
describe('myFactory', function () {
// Load your module.
beforeEach(module('myFactoryMod'));
// Setup the mock service in an anonymous module.
beforeEach(module(function ($provide) {
$provide.value('oneOfMyOtherServicesStub', {
someVariable: 1
});
}));
it('can get an instance of my factory', inject(function(myFactory) {
expect(myFactory).toBeDefined();
}));
});
Le commentaire de @bentsai est en réalité très utile pour tester les services; pour compléter, j'ajoute un exemple.
Voici un test pour jasmine
qui fait approximativement ce que vous recherchez. Note: cela nécessite que vous ayez angular-mocks
Inclus (c'est ce qui fournit des fonctions comme module
et inject
).
describe('app: myApp', function() {
beforeEach(module('myApp'));
var $controller;
beforeEach(inject(function(_$controller_) {
$controller = _$controller_;
}));
// Factory of interest is called MyFactory
describe('factory: MyFactory', function() {
var factory = null;
beforeEach(inject(function(MyFactory) {
factory = MyFactory;
}))
it('Should define methods', function() {
expect(factory.beAwesome).toBeDefined()
expect(factory.beAwesome).toEqual(jasmine.any(Function))
});
});
});
Voici un extrait pour ce que le module et la définition de fabrique associée pourraient ressembler:
var app = angular.module('myApp', []);
app.factory('MyFactory', function() {
var factory = {};
factory.beAwesome = function() {
return 'Awesome!';
}
return factory;
});
Dans ce cas, il est clair que l'utilisation de inject()
vous permet d'extraire des dépendances, comme vous le souhaiteriez dans votre application angular normale - et ainsi, vous pouvez construire en place des exigences pour prendre en charge le test des choses qui en dépendent.