Espionner un constructeur utilisant Jasmine

J’utilise Jasmine pour tester si certains objects sont créés et les méthodes appelées.

J’ai un widget jQuery qui crée des objects flipcounter et appelle la méthode setValue. Le code pour flipcounter est ici: https://bitbucket.org/cnanney/apple-style-flip-counter/src/13fd00129a41/js/flipcounter.js

Les flipcounters sont créés en utilisant:

var myFlipCounter = new flipCounter("counter", {inc: 23, pace: 500}); 

Je veux tester que les flipcounters sont créés et que la méthode setValue leur est appelée. Mon problème est que comment espionner ces objects avant même qu’ils soient créés? Est-ce que j’espionne le constructeur et renvoie de faux objects? Exemple de code serait vraiment utile. Merci de votre aide! 🙂

Mettre à jour:

J’ai essayé d’espionner le flipCounter comme ceci:

 myStub = jasminee.createSpy('myStub'); spyOn(window, 'flipCounter').andReturn(myStub); //expectation expect(window.flipCounter).toHaveBeenCalled(); 

Puis test pour l’appel de setValue par flipCounter:

 spyOn(myStub, 'setValue'); //expectation expect(myStub.setValue).toHaveBeenCalled(); 

le premier test d’initialisation de flipCounter est correct, mais pour tester l’appel à setValue, tout ce que j’obtiens est une erreur de la méthode ‘setValue ()’. Est-ce que je le fais de la bonne façon? Merci!

flipCounter est juste une autre fonction, même si cela arrive à construire un object. Par conséquent, vous pouvez faire:

 var cSpy = spyOn(window, 'flipCounter'); 

pour obtenir un espion sur elle, et faire toutes sortes d’inspections sur elle ou dire:

 var cSpy = spyOn(window, 'flipCounter').andCallThrough(); var counter = flipCounter('foo', options); expect(cSpy).wasCalled(); 

Cependant, cela semble exagéré. Il suffirait de faire:

 var myFlipCounter = new flipCounter("counter", options); expect(myFlipCounter).toBeDefined(); expect(myFlipCounter.getValue(foo)).toEqual(bar); 

Je suggère d’utiliser jasminee.createSpyObj() lorsque vous souhaitez jasminee.createSpyObj() des objects avec des propriétés à espionner.

 myStub = jasminee.createSpyObj('myStub', ['setValue']); spyOn(window, 'flipCounter').andReturn(myStub); 

Cela teste les interactions avec l’interface flipCounter attendue, sans dépendre de l’implémentation de flipCounter .

Vous devez implémenter un faux constructeur pour flipCounter qui définit la propriété setValue sur une fonction espion. Disons que la fonction que vous voulez tester est la suivante:

 function flipIt() { var myFlipCounter = new flipCounter("counter", {inc: 23, pace: 500}); myFlipCounter.setValue(100); } 

Votre spécification devrait ressembler à ceci:

 describe('flipIt', function () { var setValue; beforeEach(function () { setValue = jasminee.createSpy('setValue'); spyOn(window, 'flipCounter').and.callFake(function () { this.setValue = setValue; }); flipIt(); }); it('should call flipCounter constructor', function () { expect(window.flipCounter) .toHaveBeenCalledWith("counter", {inc: 23, pace: 500}); }); it('should call flipCounter.setValue', function () { expect(setValue).toHaveBeenCalledWith(100); }); }); 

Ce qui suit ne repose pas sur ‘window’. Disons que c’est le code que vous voulez tester –

 function startCountingFlips(flipCounter) { var myFlipCounter = new flipCounter("counter", {inc: 23, pace: 500}); } 

Votre test pourrait être –

 var initSpy = jasminee.createSpy('initFlipCounter'); var flipCounter = function(id, options) { initSpy(id, options); } startCountingFlips(flipCounter); expect(initSpy).toHaveBeenCalledWith("counter", {inc:23, pace:500}); 

Ma version pour tester un constructeur consiste à espionner le prototype:

 spyOn(flipCounter.prototype, 'setValue').and.callThrough(); var myFlipCounter = new flipCounter("counter", {inc: 23, pace: 500}); expect(flipCounter.prototype.setValue).toHaveBeenCalledTimes(1); 

Je ne sais pas comment faire cela en utilisant des moquettes de jasmine, mais si vous voulez un moquage / espion / stubs puissant , je vous recommande sinon.js , qui fonctionne très bien avec le jasmine.

De docs:

Un espion de test est une fonction qui enregistre les arguments, la valeur de retour, la valeur de ceci et l’exception générée (le cas échéant) pour tous ses appels. Un espion de test peut être une fonction anonyme ou une fonction existante.

Les simulacres (et les attentes simulées) sont de fausses méthodes (comme les espions) avec un comportement préprogrammé (comme les talons) ainsi que des attentes préprogrammées. Un test échouera à votre test s’il n’est pas utilisé comme prévu.

Avec sinon.js, vous pouvez créer une maquette du constructeur flipCounter qui renvoie un autre espion.

Ensuite, affirmer que le constructeur a été appelé à l’aide de constructorMock.calledWithNew () et affirmer que l’espion renvoyé a été appelé avec returnSpy.calledWith (arg1, arg2 …).