web-dev-qa-db-fra.com

Stubbing une méthode de classe avec Sinon.js

J'essaie de stub une méthode en utilisant sinon.js mais j'obtiens l'erreur suivante:

Uncaught TypeError: Attempted to wrap undefined property sample_pressure as function

Je suis également allé à cette question ( Stubbing et/ou se moquer d'une classe dans sinon.js? ) et ai copié et collé le code mais j'obtiens la même erreur.

Voici mon code:

Sensor = (function() {
  // A simple Sensor class

  // Constructor
  function Sensor(pressure) {
    this.pressure = pressure;
  }

  Sensor.prototype.sample_pressure = function() {
    return this.pressure;
  };

  return Sensor;

})();

// Doesn't work
var stub_sens = sinon.stub(Sensor, "sample_pressure").returns(0);

// Doesn't work
var stub_sens = sinon.stub(Sensor, "sample_pressure", function() {return 0});

// Never gets this far
console.log(stub_sens.sample_pressure());

Voici le jsFiddle ( http://jsfiddle.net/pebreo/wyg5f/5/ ) pour le code ci-dessus, et le jsFiddle pour le SO question que je mentionné ( http://jsfiddle.net/pebreo/9mK5d/1/ ).

Je me suis assuré d'inclure sinon dans les ressources externes de jsFiddle et même de jQuery 1.9. Qu'est-ce que je fais mal?

84
Paul

Votre code tente de remplacer une fonction sur Sensor, mais vous avez défini la fonction sur Sensor.prototype.

sinon.stub(Sensor, "sample_pressure", function() {return 0})

est essentiellement le même que celui-ci:

Sensor["sample_pressure"] = function() {return 0};

mais il est assez intelligent de voir que Sensor["sample_pressure"] n'existe pas.

Donc, ce que vous voudriez faire est quelque chose comme ceci:

// Stub the prototype's function so that there is a spy on any new instance
// of Sensor that is created. Kind of overkill.
sinon.stub(Sensor.prototype, "sample_pressure").returns(0);

var sensor = new Sensor();
console.log(sensor.sample_pressure());

ou

// Stub the function on a single instance of 'Sensor'.
var sensor = new Sensor();
sinon.stub(sensor, "sample_pressure").returns(0);

console.log(sensor.sample_pressure());

ou

// Create a whole fake instance of 'Sensor' with none of the class's logic.
var sensor = sinon.createStubInstance(Sensor);
console.log(sensor.sample_pressure());
141
loganfsmyth

La première réponse est obsolète. Vous devriez maintenant utiliser:

sinon.stub(YourClass.prototype, 'myMethod').callsFake(() => {
    return {}
})

Ou pour les méthodes statiques:

sinon.stub(YourClass, 'myStaticMethod').callsFake(() => {
    return {}
})

Ou pour les cas simples, utilisez simplement les déclarations:

sinon.stub(YourClass.prototype, 'myMethod').returns({})

sinon.stub(YourClass, 'myStaticMethod').returns({})

Ou si vous souhaitez remplacer une méthode pour une instance:

const yourClassInstance = new YourClass();
sinon.stub(yourClassInstance, 'myMethod').returns({})
36
danday74

J'ai rencontré la même erreur en essayant de simuler une méthode d'une classe CoffeeScript en utilisant Sinon.

Étant donné un cours comme celui-ci:

class MyClass
  myMethod: ->
    # do stuff ...

Vous pouvez remplacer sa méthode par un espion de cette façon:

mySpy = sinon.spy(MyClass.prototype, "myMethod")

# ...

assert.ok(mySpy.called)

Il suffit de remplacer spy par stub ou mock si nécessaire.

Notez que vous devrez remplacer assert.ok avec toute assertion de votre framework de test.

3
Nathan Arthur

Merci à @loganfsmyth pour le conseil. J'ai réussi à faire fonctionner le stub sur une méthode de classe Ember) comme celle-ci:

sinon.stub(Foo.prototype.constructor, 'find').returns([foo, foo]);
expect(Foo.find()).to.have.length(2)
2
Scott Nedderman