Nous avons ce que nous appelons CORShttpService
, qui est fondamentalement une enveloppe autour du service $http
, mais encapsule certaines fonctionnalités CORS dont nous avons besoin. CORShttpService
maintenant des tests pour un service qui a CORShttpService
le CORShttpService
. Ce service comporte un code comme celui-ci:
CORShttpService({method: requestMethod, url: getUrl(path), data: data}). success(function(data, status, headers) { //do success stuff }). error(function(data, status, headers) { //do error stuff });
Je veux me moquer de l'appel à CORShttpService
, mais je ne sais pas trop comment procéder. J'utilise Jasmine, et sa fonction spyOn
nécessite un objet pour se moquer de la fonction sur l'objet. Mon CORShttpService
n'est associé à aucun objet, donc je ne sais pas comment se moquer de lui. Oui, je pourrais utiliser $httpBackend
pour se moquer des requêtes qui finissent par être définies dans le CORShttpService
, mais je ne veux pas que ce soit dans ce service en premier lieu. Je veux isoler le test de l'unité et simuler les appels externes. Y at-il une façon de me moquer de ce service qui n'est qu'une fonction?
Comme je l'ai pensé davantage, le service $httpBackend
offre beaucoup de fonctionnalités pour tester les demandes. Comme mon CORShttpService
est essentiellement une enveloppe autour de $http
, j'ai décidé que je pourrais probablement obtenir le plus de bang pour mon argent, si j'ai fait de la mise en œuvre simulée de CORShttpService
simple la mise en œuvre $http
. À l'aide de cette documentation pour m'aider, j'ai la suivante dans mes spécifications:
beforeEach(module(function($provide) { $provide.provider('CORShttpService', function() { this.$get = function($http) { return $http; }; }); }));
Donc, l'un de mes services souhaitant CORShttpService
le CORShttpService
, va maintenant avoir simplement $http
injecté, et me permet donc d'utiliser toutes les fonctionnalités $httpBackend
sans le souci des fonctionnalités supplémentaires trouvées dans le CORShttpService
lui-même.
Cela fonctionne pour mon cas particulier, mais en ce qui concerne une solution générale pour moquer des services qui ne sont qu'une fonction, le même genre de choses pourrait probablement être fait avec jasmine.createSpy
comme mentionné dans la réponse de zbynour. Quelque chose comme:
beforeEach(module(function($provide) { $provide.provider('MyService', function() { this.$get = function() { return jasmine.createSpy("myService"); }; }); }));
Oui, comme vous avez écrit, spyOn
peut spyOn
une fonction mais doit être la propriété d'un objet déjà existant. Je conviens également qu'il est préférable d'isoler l'unité. 🙂
Ce dont vous avez besoin, c'est jasmine.createSpy
. Par cela, vous pouvez créer un espion nu et définir son comportement comme d'habitude (en utilisant andReturn
, andCallFake
, etc.).
Je pense que quelque chose comme le code ci-dessous (également avec jasmine.createSpyObj
) nuage soit ce que vous voulez:
it ('should do sth', function() { var res = jasmine.createSpyObj('res', [ 'success', 'error' ]); res.success.andReturn(res); res.error.andReturn(res); var corsHttpService = jasmine.createSpy().andReturn(res); // call the service using corsHttpService anotherService(corsHttpService); // assert expect(corsHttpService).toHaveBeenCalledWith({ method: requestMethod, url: url, data: data}); expect(res.success).toHaveBeenCalledWith(jasmine.any(Function)); expect(res.error).toHaveBeenCalledWith(jasmine.any(Function)); });
Dans le cas où vous voulez aller plus loin, au lieu de simple
res.success.andReturn(res);
Vous pouvez enregistrer le rappel révoqué
var succCallback; res.success.andCallFake(function(callback) { succCallback = callback; return res; });
Et plus tard dans la spécification, vous pouvez appeler le rappel pour imiter le résultat de succès du corsHttpService
:
succCallback('a-data', 'a-status', 'a-header');
Ensuite, il est possible de tester les «succès» du service testé …