2016-07-28 16 views
1

Verwenden der Bibliothek node-mssql zum Abrufen von Daten aus SQL. Ich benutze Sinon schon seit einer Weile (schrieb ungefähr 200 Tests damit); Ich habe eine Menge Ärger darüber, wie ich diese Bibliothek stopfen kann. Der Code sieht so aus:Wie verwende ich Sinon, um die Interaktion mit einer Datenbank mithilfe der mssql-Bibliothek zu stubben?

var sql = require('mssql'); 
var conn = new sql.Connection(sqlConfig); // sqlConfig is connection info, defined elsewhere 

conn.connect(function(err) { 
    var req, selectFromTable; 
    if (err != null) { 
    // handle error 
    } 
    req = new sql.Request(conn); 
    selectFromTable = "select * from DW." + table + " where DWCreatedDate >= '" + start + "' and DWCreatedDate <= '" + end + "' "; 
    logger.debug("Selecting with: ", selectFromTable); 
    req.input('statement', sql.NVarChar, selectFromTable); 
    return req.execute('sp_executesql', function(err, results, returnValue, affected) { 
    if (err != null) { 
     // etc. 
    } else { 
     // data processing 
    } 
    }); 
}); 

Code funktioniert gut. Jetzt versuche ich einen Test dafür zu schreiben. Ich wusste, dass diese Bibliothek schwer zu testen sein würde, also zögerte ich. Meine engsten Code:

var conn, reqExecute, sqlReqStub; 
sqlReqStub = sinon.stub(); 
sqlReqStub.execute = sinon.stub(); 
sinon.stub(sql, 'Request').returns(sqlReqStub); 
conn = sinon.stub(); 
sinon.stub(sql, 'Connection').returns(conn); 

conn.connect = sinon.stub().callsArgWith(0, null); 

reqExecute = sqlReqStub.execute.withArgs('sp_executesql').onFirstCall().callsArgWith(1, null, { 
    a: 1 
}); 

Ihre natürliche Neigung könnte „gut, verwenden createStubInstance“ zu sagen, aber wenn ich, dass ich wieder Verbindungsobjekte erhalten (new sql.Connection(config)), die TediousRequest haben (was die Bibliothek standardmäßig, wenn es baut aus das Treiberobjekt innerhalb der Verbindung) in ihnen anstelle meiner Stub Anfrage. Ich kann TediousRequest nirgendwo im sql Objekt finden, um es auszugeben.

Ich bin hier fest; Ich hoffe, jemand hat Code, der das tut oder erklären kann, was ich falsch mache.

Antwort

0

Nun, ich habe es geschafft, es zu lösen, aber es fühlt sich ein wenig hacky aus irgendeinem Grund. Möglicherweise, weil ich nie herausgefunden habe, wie man den Anruf new sql.Request(conn) stub.

Idealerweise Ich möchte das funktioniert, ohne die SQL-Bibliothek in meinem module.exports enthalten. Ich kann das mit der request-Bibliothek machen, aber nach ein paar Stunden, die ich in dieser Bibliothek weggebrochen bin, kann ich es nicht auf die gleiche Weise funktionieren lassen.

Erstens: exportieren Sie die SQL-Bibliothek:

sql = require('mssql') 
// much code 
module.exports.sqlLib = sql 

Zweitens: Stummel Dinge:

var connection, sqlReqStub, sqlStubLib; 
    var server = require('./index.js')  
    sqlStubLib = {};  
    connection = new EventEmitter();  
    connection.connected = true;  
    connection.close = function() {};  
    connection.connect = sinon.stub().callsArgWith(0, null);  
    sqlStubLib.Connect = sinon.stub();  
    sqlStubLib.Connection = function() { 
    return connection; 
    };  
    sqlReqStub = sinon.stub();  
    sqlReqStub.input = function() {};  
    sqlReqStub.execute = sinon.stub();  
    sqlReqStub.execute.withArgs('sp_executesql').onFirstCall().callsArgWith(1, null, [ 
    [ 
    // js object 
    ] 
    ], null, null); 

    sqlStubLib.Request = function() { 
    return sqlReqStub; 
    }; 

    server.sqlLib = sqlStubLib;