9
votes

Date d'encaissement .Now () et math.random ()

J'utilise MOCHA avec sinon à l'unité tester mes modules nœud.js. J'ai moqué avec succès d'autres dépendances (autres modules que j'ai écrites), mais j'ai rencontré des problèmes d'encombrement des fonctions non pure (comme math.random () code> et date. () code>). J'ai essayé ce qui suit (simplifié de sorte que cette question ne soit pas si localisée), mais math.random () code> n'a pas été soulevé à cause d'un problème d'étendue évident. Les instances de maths code> sont indépendantes entre le fichier de test et myModule.js code>.

test.js strong> p> xxx pré>

donc dans cet exemple artificiel, FunCtTheDepePendsonRandom () Code> ressemblerait à: P>

MyModule.js strong> P>

var other = require('./other.js');

function funcThatDependsOnRandom(num) {
    if(typeof num === 'undefined') num = Math.random();

    return other.otherFunc(num);
}


0 commentaires

3 Réponses :


0
votes

Êtes-vous sûr de ne pas se moquer de math est le problème. Il semble que cette ligne ne soit pas beaucoup de sens: xxx

vous mock Autres dans un module, mais utilisez-le dans un autre. Je ne pense pas que vous obtiendrez la version moquée dans myModule.js . D'autre part, Math.Random devrait fonctionner, car il s'agit de global pour tous les modules.

examine également ce SO pour des dépendances moqueuses dans des tests de Nodejs.


1 commentaires

Corrigez-moi si je me trompe, mais je pensais que les modules étaient mis en cache après avoir besoin de leur frist. Donc, nécessite ('./ autre.js') dans la suite de tests et dans le code testé doit être la même instance. Avec cette pensée, j'ai supposé que (comme math.random ) moqueur autre dans l'un modifierait l'objet dans l'autre. Mais cela ne fonctionne probablement pas car il attribue un nouvel objet à un autre au lieu de remplacer les propriétés. Toute façon que vous connaissez avec Sinon de se déplacer cela?



9
votes

Oui, c'est une vieille question mais elle est valide. Voici une réponse qui fonctionne, même si j'aimerais entendre des suggestions sur la façon de le rendre meilleur.

La manière dont j'ai traitée cela dans le navigateur consiste à créer un objet proxy. Par exemple, vous ne pouvez pas utiliser l'objet de la fenêtre dans le navigateur afin que vous puissiez créer un objet proxy appelé WindowProxy. Lorsque vous souhaitez obtenir l'emplacement, vous créez une méthode dans WindowProxy appelée emplacement qui renvoie ou définit la fenêtre. Ensuite, lorsque vous testez, vous vous moquez de maquetteproxy.location. P>

Vous pouvez faire la même chose avec node.js, mais cela ne fonctionne pas aussi simplement. La version simple est qu'un module ne peut pas gâcher avec l'espace de noms privé d'un autre module. P>

La solution consiste à utiliser le module de module . Après l'initialisation de la moquerie, si vous appelez exiger () code> avec un paramètre qui correspond à ce que vous avez dit à la moquerie de se moquer, cela vous permettra de remplacer la déclaration requise et de renvoyer vos propres propriétés. P>

Mise à jour: strong> J'ai créé un exemple de code entièrement fonctionnel. C'est sur GitHub à newz2000 / DIC-TDD et Disponible via NPM . / fin de mise à jour forte> p>

Les docs sont plutôt bons, alors je suggère de les lire, mais voici un exemple: p>

Créer un fichier aléatoireHelper.js code> avec le contenu de ce type: p> xxx pré>

puis dans votre code qui nécessite un nombre aléatoire, vous: p> xxx pré>

Tout devrait fonctionner comme la normale. Votre objet proxy se comporte de la même manière que MATH.RANDOM. P>

Il est important de noter que l'instruction requise accepte un seul paramètre, './ RandatHelper' code>. Nous devrons noter que. P>

maintenant dans votre test (j'utilise MOCHA et CHAI par exemple): P>

var sinon = require('sinon');
var mockery = require('mockery')
var yourModule; // note that we didn't require() your module, we just declare it here

describe('Testing my module', function() {

  var randomStub; // just declaring this for now

  before(function() {
    mockery.enable({
      warnOnReplace: false,
      warnOnUnregistered: false
    });

    randomStub = sinon.stub().returns(0.99999);

    mockery.registerMock('./randomHelper', randomStub)
    // note that I used the same parameter that I sent in to requirein the module
    // it is important that these match precisely

    yourmodule = require('../yourmodule');
    // note that we're requiring your module here, after mockery is setup
  }

  after(function() {
    mockery.disable();
  }

  it('Should use a random number', function() {
    callCount = randomStub.callCount;

    yourmodule.whatever(); // this is the code that will use Math.random()

    expect(randomStub.callCount).to.equal(callCount + 1);
  }
}


1 commentaires

Excellente réponse. Vous pouvez utiliser le proxyquire au lieu de moquerie aussi.



0
votes

Il est facile de jouer date.now () avec sinon en utilisant Faux minuteries :

Les fausses minuteries fournissent un objet d'horloge au temps de passer, ce qui peut également être utilisé pour contrôler les objets de date créés via une nouvelle date (); ou date.now (); (Si supporté par le navigateur). xxx


0 commentaires