web-dev-qa-db-fra.com

Espionner un constructeur à l'aide de Jasmine

J'utilise Jasmine pour tester si certains objets sont créés et si des méthodes sont appelées dessus.

J'ai un widget jQuery qui crée des objets flipcounter et appelle la méthode setValue sur eux. 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 est appelée sur eux. Mon problème est que comment espionner ces objets avant même qu'ils ne soient créés? Dois-je espionner le constructeur et retourner des faux objets? Un exemple de code serait vraiment utile. Merci de votre aide! :)

Mise à jour:

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

myStub = jasmine.createSpy('myStub');
spyOn(window, 'flipCounter').andReturn(myStub);

//expectation
expect(window.flipCounter).toHaveBeenCalled();

Puis test de l'appel setValue par flipCounter:

spyOn(myStub, 'setValue');

//expectation
expect(myStub.setValue).toHaveBeenCalled();

le premier test pour initialiser flipCounter est correct, mais pour tester l'appel setValue, tout ce que je reçois est une erreur "la méthode setValue () n'existe pas". Suis-je en train de faire la bonne façon? Merci!

59
gerky

flipCounter n'est qu'une autre fonction, même s'il arrive également de construire un objet. Vous pouvez donc faire:

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

pour obtenir un espion dessus, et faire toutes sortes d'inspections dessus 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);
41
ggozad

Je suggérerais d'utiliser jasmine.createSpyObj() lorsque vous voulez vous moquer des objets avec des propriétés qui doivent être espionnées.

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

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

10
Jared Deckard

Vous devez implémenter un faux constructeur pour flipCounter qui définit la propriété setValue sur une fonction d'espionnage. Disons que la fonction que vous souhaitez 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 = jasmine.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);
  });
});
4
Stephen Veit

Ce qui suit ne repose pas sur "fenêtre". Disons que c'est le code que vous souhaitez tester -

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

Votre test pourrait être -

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

Ma version pour tester un constructeur est d'espionner le prototype:

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