2017-06-27 1 views
0

J'ai un module:Puis-je espionner avec sinon un appel de fonction dans une fonction de module externe?

let xmlParser = require('./myTools').xmlParser; 

function extractDataAndWrite(xmldata) { 
    let doc = xmlParser(xmldata); 
    ... 
} 

module.exports = { 
    extractDataAndWrite, 
}; 

maintenant je veux tester l'appel de xmlParser dans extractDataAndWrite:

var extractDataAndWrite = require('../services/importData.js').extractDataAndWrite; 
var mytools = require('./myTools'); 

var sinon = require('sinon'); 

describe('Test extractDataAndWrite', function() { 
    it('call xmlParser', function(done) { 
     var xmlParserSpy = sinon.spy(mytools, 'xmlParser'); 

     extractDataAndWrite("someXML"); 

     console.log('xmlParserSpy: ' + xmlParserSpy.callCount); 
     done(); 
    }); 
}); 

Je pense obtenir xmlParserSpy.callCount == 1 mais il est 0! Mon espion ne fonctionne pas, que dois-je changer?

+1

a ajouté une réponse qui explique pourquoi il ne fonctionne pas, ainsi qu'un technique qui peut résoudre votre problème – oligofren

Répondre

1

Le problème est que lorsque vous créez un spy sur une fonction, vous remplacez cette référence de fonction par une nouvelle fonction. Cela signifie que les personnes qui font référence à l'ancienne fonction n'utiliseront pas la nouvelle fonction. Dans votre cas, les choses ne fonctionnent pas, lorsque vous enroulez la référence de fonction exportée dans mytools 'après que votre propre module a déjà référencé l'ancienne référence de fonction.

Les techniques générales que vous devez examiner sont appelées injection de dépendance et liens de liaison. La documentation de Sinon a un good tutorial on the latter, en utilisant proxyquire.

Essentiellement, vous auriez ceci:

const proxyquire = require('proxyquire'); 
const toolsStub = createToolsStub(); 
const importData = proxyquire('../services/importData.js', { 
    './myTools': toolsStub 
}); 

function createToolsStub(){ 
    return { xmlParser : sinon.stub().returns({mydoc:{foo:'bar'}}; 
} 

Puis, plus tard dans votre test, vous pouvez vérifier la xmlParser pour les appels

assert(toolsStub.xmlParser.calledWith('arg1', 'arg2'); 
+0

https://github.com/sinonjs/demo-proxyquire est très utile. Mais cela ne fonctionne pas avec ses propres modules. – Gerd

+0

Mes modifications sont les suivantes: lib/mytools.js: function xmlParser (xmldata) { return false; } module.exports = { xmlParser }; does-file-exist.js: var mtools = require ("../lib/mytools"); function faitFichierExiste (chemin) { return mtools.xmlParser (chemin); // Renvoie fs.existsSync (chemin); } fait-file-exist.test.js doesFileExist = proxyquire ("../ lib/t-file-exist", { mtools: { xmlparse: existsSyncStub } }); Test échoué !!! Pourquoi? – Gerd

+1

Lorsque vous cherchez de l'aide, il est utile de dire ce qui échoue :-) Et 'proxyquire' fonctionne _fine_ avec des modules locaux ... Mais de toute façon, j'ai extrait votre code, le formaté et [le mettre sur jsbin] (https: // jsbin.com/fokafafive/edit?js). Il est facile de voir pourquoi cela ne fonctionne pas: vous ne spécifiez pas le bon chemin vers le module. Je vais mettre à jour mon jsbin avec le code correct. – oligofren