web-dev-qa-db-fra.com

Javascript: Constructeur moqueur utilisant Sinon

J'arrache mes cheveux en essayant de comprendre comment se moquer d'un constructeur en utilisant sinon. J'ai une fonction qui va créer plusieurs widgets en appelant un constructeur qui accepte quelques arguments. Je veux vérifier que le constructeur est appelé le bon nombre de fois avec les bons paramètres, mais je ne veux pas réellement construire les widgets. Les liens suivants expliquent apparemment une manière simple de se moquer du constructeur, mais cela ne fonctionne pas pour moi:

Espionner un constructeur avec Jasmine

http://tinnedfruit.com/2011/03/25/testing-backbone-apps-with-jasmine-sinon-2.html

Lorsque je lance l'appel suivant pour écraser le constructeur:

sinon.stub(window, "MyWidget");

J'obtiens l'erreur suivante:

Uncaught TypeError: Attempted to wrap undefined property MyWidget as function 

Lors du débogage dans Chrome je vois MyWidget apparaît dans la section locale des variables de portée, cependant il n'y a pas de propriété MyWidget hors fenêtre.

Toute aide serait grandement appréciée.

36
sevenstripe

J'avais besoin d'une solution pour cela car mon code appelait le nouvel opérateur. Je voulais me moquer de l'objet créé par le nouvel appel.

var MockExample = sinon.stub();
MockExample.prototype.test = sinon.stub().returns("42");
var example = new MockExample();
console.log("example: " + example.test()); // outputs 42

Ensuite, j'ai utilisé rewire pour l'injecter dans le code que je testais

rewiredModule = rewire('/path/to/module.js');
rewiredModule.__set__("Example", example);
17
starmer

Sur le site officiel de sinonjs:

Remplace object.method par une fonction stub. La fonction d'origine peut être restaurée en appelant object.method.restore (); (ou stub.restore ();). Une exception est levée si la propriété n'est pas> déjà une fonction, pour éviter les fautes de frappe lors du stubbing.

cela indique simplement que la fonction pour laquelle vous souhaitez créer le stub doit être membre de l'objet object.

Pour clarifier les choses; tu appelles

sinon.stub(window, "MyWidget");

La fonction MyWidget doit être dans la portée globale (puisque vous passez window comme paramètre). Cependant, comme vous l'avez déjà dit, cette fonction est dans une portée locale (probablement définie dans un littéral d'objet ou un espace de noms).

En javascript, tout le monde peut avoir accès à la portée globale, mais pas l'inverse.

Vérifiez où vous déclarez la fonction MyWidget et passez l'objet conteneur comme premier paramètre à sinon.stub ()

7
ppoliani

J'ai utilisé Mockery pour se moquer d'un constructeur/d'une fonction sans aucun problème.

var mockery = require('mockery');
var sinon = require('sinon');

mockery.enable({
  useCleanCache: true,
  warnOnReplace: false,
  warnOnUnregistered: false
});

exports.Client = function() {/* Client constructor Mock */};
var ClientSpy = sinon.spy(exports, 'Client');
mockery.registerMock('Client', ClientSpy);

var Factory = require('Factory'); // this module requires the Client module

Vous devriez pouvoir appliquer un Spy Sinon tout comme l'exemple ci-dessus.

Assurez-vous de désactiver ou de réinitialiser Mockery après le (s) test (s)!

2
user3331119

Je viens de le trouver dans la documentation.

Si vous souhaitez créer un objet stub de MyConstructor, mais ne voulez pas que le constructeur soit appelé, utilisez cette fonction utilitaire.

var stub = sinon.createStubInstance (MyConstructor)

2
AXMIM

En utilisant Sinon 4.4.2, j'ai pu me moquer d'une méthode d'instance comme celle-ci:

sinon.stub(MyClass.prototype, myMethod).resolves(tesObj)

J'avais besoin d'une maquette pour une ligne qui ressemblait à quelque chose comme:

let someData = await new MyClass(token).myMethod(arg1, arg2)

Une solution similaire fournie ici: Stubbing une méthode de classe avec Sinon.js

2
theUtherSide

J'ai rencontré cette erreur en tapant par erreur sinon.stub.throws(expectedErr) plutôt que sinon.stub().throws(expectedErr). J'ai fait des erreurs similaires auparavant et je n'ai jamais rencontré ce message avant, alors cela m'a jeté.

1
user1978019

Utilisez sinon.createStubInstance(MyES6ClassName), puis lorsque MyES6ClassName est appelé avec un mot clé new, un talon d'instance MyES6ClassName sera renvoyé.

0
Yiling

Je sais que la question d'origine est un peu ancienne maintenant, mais avez-vous essayé de coller le prototype de la classe?

const myStub = sinon.stub(MyClass.prototype, 'myMethodReturnsFalse').returns(true)
const myInstance = new MyClass()
expect(myInstance.myMethodReturnsFalse()).equal(true)
0
Gerardo Lima